aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hartman <ghartman@google.com>2019-07-11 17:40:40 -0700
committerGreg Hartman <ghartman@google.com>2019-07-11 17:43:12 -0700
commitb13cae464cd3de87e42dbeb8257ea0ef41cfe282 (patch)
tree1a7d1b407c04e79fde0f04607e2bb3bddc6c6799
parent1edaa80c2112b8a78deaf549ec282c7187dbf840 (diff)
parent681e860638e5fc6eed856bda1f6a087473afc793 (diff)
downloadlibdrm-pie-gsi.tar.gz
Merge aosp/master into aosp/pie-gsipie-gsi
BUG: 123765087 BUG: 123764798 (Milestone) BUG: 77276633 (OKR) Test: Builds Change-Id: Id8c2e6140ac987f8dd1c0f189559459bbb51dbc3
-rw-r--r--.editorconfig4
-rw-r--r--.gitignore58
-rw-r--r--.gitlab-ci.yml159
-rw-r--r--Android.bp2
-rw-r--r--CONTRIBUTING.rst105
-rw-r--r--Makefile.am41
-rw-r--r--Makefile.sources4
-rw-r--r--OWNERS5
-rw-r--r--README41
-rw-r--r--README.rst61
-rw-r--r--RELEASING6
-rw-r--r--amdgpu/.editorconfig13
-rw-r--r--amdgpu/Android.bp5
-rw-r--r--amdgpu/Android.sources.bp5
-rw-r--r--amdgpu/Makefile.am6
-rw-r--r--amdgpu/Makefile.sources9
-rwxr-xr-xamdgpu/amdgpu-symbol-check30
-rw-r--r--amdgpu/amdgpu.h420
-rw-r--r--amdgpu/amdgpu_asic_id.c161
-rw-r--r--amdgpu/amdgpu_asic_id.h165
-rw-r--r--amdgpu/amdgpu_bo.c461
-rw-r--r--amdgpu/amdgpu_cs.c363
-rw-r--r--amdgpu/amdgpu_device.c180
-rw-r--r--amdgpu/amdgpu_gpu_info.c141
-rw-r--r--amdgpu/amdgpu_internal.h54
-rw-r--r--amdgpu/amdgpu_vamgr.c200
-rw-r--r--amdgpu/amdgpu_vm.c50
-rw-r--r--amdgpu/handle_table.c72
-rw-r--r--amdgpu/handle_table.h41
-rw-r--r--amdgpu/meson.build65
-rw-r--r--amdgpu/util_hash.c387
-rw-r--r--amdgpu/util_hash.h107
-rw-r--r--amdgpu/util_hash_table.c262
-rw-r--r--amdgpu/util_hash_table.h73
-rw-r--r--android/gralloc_handle.h111
-rwxr-xr-xautogen.sh10
-rw-r--r--configure.ac98
-rw-r--r--data/Makefile.am25
-rw-r--r--data/amdgpu.ids197
-rw-r--r--data/meson.build27
-rw-r--r--etnaviv/Makefile.am2
-rw-r--r--etnaviv/Makefile.sources1
-rwxr-xr-xetnaviv/etnaviv-symbol-check8
-rw-r--r--etnaviv/etnaviv_bo.c36
-rw-r--r--etnaviv/etnaviv_bo_cache.c30
-rw-r--r--etnaviv/etnaviv_cmd_stream.c64
-rw-r--r--etnaviv/etnaviv_device.c14
-rw-r--r--etnaviv/etnaviv_drm.h58
-rw-r--r--etnaviv/etnaviv_drmif.h25
-rw-r--r--etnaviv/etnaviv_gpu.c82
-rw-r--r--etnaviv/etnaviv_perfmon.c185
-rw-r--r--etnaviv/etnaviv_pipe.c12
-rw-r--r--etnaviv/etnaviv_priv.h47
-rw-r--r--etnaviv/meson.build59
-rw-r--r--exynos/Makefile.am2
-rwxr-xr-xexynos/exynos-symbol-check4
-rw-r--r--exynos/exynos_drm.c36
-rw-r--r--exynos/exynos_drmif.h8
-rw-r--r--exynos/exynos_fimg2d.c59
-rw-r--r--exynos/exynos_fimg2d.h21
-rw-r--r--exynos/fimg2d_reg.h21
-rw-r--r--exynos/meson.build54
-rw-r--r--freedreno/Makefile.am3
-rw-r--r--freedreno/Makefile.sources1
-rwxr-xr-xfreedreno/freedreno-symbol-check17
-rw-r--r--freedreno/freedreno_bo.c94
-rw-r--r--freedreno/freedreno_bo_cache.c14
-rw-r--r--freedreno/freedreno_device.c24
-rw-r--r--freedreno/freedreno_drmif.h7
-rw-r--r--freedreno/freedreno_pipe.c52
-rw-r--r--freedreno/freedreno_priv.h89
-rw-r--r--freedreno/freedreno_ringbuffer.c127
-rw-r--r--freedreno/freedreno_ringbuffer.h65
-rw-r--r--freedreno/kgsl/kgsl_bo.c6
-rw-r--r--freedreno/kgsl/kgsl_device.c6
-rw-r--r--freedreno/kgsl/kgsl_pipe.c7
-rw-r--r--freedreno/kgsl/kgsl_priv.h4
-rw-r--r--freedreno/kgsl/kgsl_ringbuffer.c20
-rw-r--r--freedreno/meson.build77
-rw-r--r--freedreno/msm/msm_bo.c17
-rw-r--r--freedreno/msm/msm_device.c7
-rw-r--r--freedreno/msm/msm_pipe.c57
-rw-r--r--freedreno/msm/msm_priv.h42
-rw-r--r--freedreno/msm/msm_ringbuffer.c377
-rw-r--r--include/drm/README41
-rw-r--r--include/drm/amdgpu_drm.h645
-rw-r--r--include/drm/drm.h108
-rw-r--r--include/drm/drm_fourcc.h399
-rw-r--r--include/drm/drm_mode.h299
-rw-r--r--include/drm/drm_sarea.h8
-rw-r--r--include/drm/i915_drm.h343
-rw-r--r--include/drm/mga_drm.h12
-rw-r--r--include/drm/msm_drm.h (renamed from freedreno/msm/msm_drm.h)43
-rw-r--r--include/drm/nouveau_class.h651
-rw-r--r--include/drm/nouveau_drm.h171
-rw-r--r--include/drm/nouveau_ioctl.h128
-rw-r--r--include/drm/qxl_drm.h84
-rw-r--r--include/drm/r128_drm.h10
-rw-r--r--include/drm/radeon_drm.h128
-rw-r--r--include/drm/savage_drm.h20
-rw-r--r--include/drm/sis_drm.h10
-rw-r--r--include/drm/tegra_drm.h567
-rw-r--r--include/drm/vc4_drm.h140
-rw-r--r--include/drm/via_drm.h8
-rw-r--r--include/drm/virtgpu_drm.h1
-rw-r--r--include/drm/vmwgfx_drm.h44
-rw-r--r--intel/Android.sources.bp1
-rw-r--r--intel/Makefile.am2
-rw-r--r--intel/Makefile.sources2
-rw-r--r--intel/i915_pciids.h461
-rwxr-xr-xintel/intel-symbol-check4
-rw-r--r--intel/intel_bufmgr.c68
-rw-r--r--intel/intel_bufmgr_fake.c20
-rw-r--r--intel/intel_bufmgr_gem.c144
-rw-r--r--intel/intel_chipset.c85
-rw-r--r--intel/intel_chipset.h142
-rw-r--r--intel/intel_decode.c25
-rw-r--r--intel/meson.build106
-rw-r--r--intel/mm.c4
-rw-r--r--intel/mm.h4
-rw-r--r--intel/test_decode.c8
-rw-r--r--libdrm_macros.h4
-rw-r--r--libkms/Makefile.am2
-rw-r--r--libkms/api.c20
-rw-r--r--libkms/dumb.c4
-rw-r--r--libkms/exynos.c26
-rw-r--r--libkms/intel.c4
-rw-r--r--libkms/internal.h4
-rwxr-xr-xlibkms/kms-symbol-check4
-rw-r--r--libkms/linux.c14
-rw-r--r--libkms/meson.build75
-rw-r--r--libkms/nouveau.c4
-rw-r--r--libkms/radeon.c4
-rw-r--r--libkms/vmwgfx.c4
-rw-r--r--man/drm-kms.xml4
-rw-r--r--man/drm-memory.xml4
-rw-r--r--man/drm.xml6
-rw-r--r--man/drmAvailable.xml4
-rw-r--r--man/drmHandleEvent.xml4
-rw-r--r--man/drmModeGetResources.xml4
-rw-r--r--man/meson.build67
-rw-r--r--meson.build386
-rw-r--r--meson_options.txt143
-rw-r--r--nouveau/Makefile.am2
-rw-r--r--nouveau/abi16.c4
-rw-r--r--nouveau/bufctx.c14
-rw-r--r--nouveau/meson.build59
-rwxr-xr-xnouveau/nouveau-symbol-check4
-rw-r--r--nouveau/nouveau.c56
-rw-r--r--nouveau/pushbuf.c24
-rw-r--r--omap/Android.bp12
-rw-r--r--omap/Android.sources.bp8
-rw-r--r--omap/Makefile.am2
-rw-r--r--omap/meson.build54
-rwxr-xr-xomap/omap-symbol-check4
-rw-r--r--omap/omap_drm.c42
-rw-r--r--radeon/Makefile.am2
-rw-r--r--radeon/meson.build64
-rwxr-xr-xradeon/radeon-symbol-check4
-rw-r--r--radeon/radeon_bo.c31
-rw-r--r--radeon/radeon_bo_gem.c19
-rw-r--r--radeon/radeon_cs.c27
-rw-r--r--radeon/radeon_cs_gem.c7
-rw-r--r--radeon/radeon_cs_space.c11
-rw-r--r--radeon/radeon_surface.c12
-rw-r--r--rockchip/Android.bp13
-rw-r--r--rockchip/Makefile.am20
-rw-r--r--rockchip/libdrm_rockchip.pc.in11
-rw-r--r--rockchip/rockchip_drm.c299
-rw-r--r--rockchip/rockchip_drm.h73
-rw-r--r--rockchip/rockchip_drmif.h79
-rw-r--r--tegra/Makefile.am4
-rw-r--r--tegra/meson.build53
-rw-r--r--tegra/private.h3
-rwxr-xr-xtegra/tegra-symbol-check11
-rw-r--r--tegra/tegra.c85
-rw-r--r--tegra/tegra.h5
-rw-r--r--tests/Makefile.am12
l---------tests/amdgpu/.editorconfig1
-rw-r--r--tests/amdgpu/Makefile.am13
-rw-r--r--tests/amdgpu/amdgpu_test.c229
-rw-r--r--tests/amdgpu/amdgpu_test.h226
-rw-r--r--tests/amdgpu/basic_tests.c1183
-rw-r--r--tests/amdgpu/bo_tests.c133
-rw-r--r--tests/amdgpu/cs_tests.c74
-rw-r--r--tests/amdgpu/deadlock_tests.c379
-rw-r--r--tests/amdgpu/decode_messages.h (renamed from tests/amdgpu/uvd_messages.h)43
-rw-r--r--tests/amdgpu/frame.h2
-rw-r--r--tests/amdgpu/meson.build34
-rw-r--r--tests/amdgpu/uvd_enc_tests.c491
-rw-r--r--tests/amdgpu/uve_ib.h527
-rw-r--r--tests/amdgpu/vce_ib.h17
-rw-r--r--tests/amdgpu/vce_tests.c296
-rw-r--r--tests/amdgpu/vcn_tests.c404
-rw-r--r--tests/amdgpu/vm_tests.c255
-rw-r--r--tests/drmdevice.c91
-rw-r--r--tests/drmsl.c28
-rw-r--r--tests/drmstat.c419
-rw-r--r--tests/etnaviv/Makefile.am2
-rw-r--r--tests/etnaviv/etnaviv_2d_test.c4
-rw-r--r--tests/etnaviv/etnaviv_bo_cache_test.c4
-rw-r--r--tests/etnaviv/meson.build45
-rw-r--r--tests/etnaviv/write_bmp.c4
-rw-r--r--tests/exynos/Makefile.am1
-rw-r--r--tests/exynos/exynos_fimg2d_event.c27
-rw-r--r--tests/exynos/exynos_fimg2d_perf.c34
-rw-r--r--tests/exynos/exynos_fimg2d_test.c68
-rw-r--r--tests/exynos/meson.build54
-rw-r--r--tests/kms/Makefile.am3
-rw-r--r--tests/kms/kms-steal-crtc.c4
-rw-r--r--tests/kms/kms-universal-planes.c4
-rw-r--r--tests/kms/libkms-test-crtc.c4
-rw-r--r--tests/kms/libkms-test-device.c13
-rw-r--r--tests/kms/libkms-test-framebuffer.c4
-rw-r--r--tests/kms/libkms-test-plane.c4
-rw-r--r--tests/kms/libkms-test-screen.c4
-rw-r--r--tests/kms/meson.build49
-rw-r--r--tests/kmstest/Makefile.am1
-rw-r--r--tests/kmstest/meson.build30
-rw-r--r--tests/meson.build86
-rw-r--r--tests/modeprint/Makefile.am2
-rw-r--r--tests/modeprint/meson.build29
-rw-r--r--tests/modeprint/modeprint.c53
-rw-r--r--tests/modetest/Makefile.am1
-rw-r--r--tests/modetest/buffers.c4
-rw-r--r--tests/modetest/cursor.c4
-rw-r--r--tests/modetest/meson.build29
-rw-r--r--tests/modetest/modetest.c459
-rw-r--r--tests/nouveau/Makefile.am1
-rw-r--r--tests/nouveau/meson.build30
-rw-r--r--tests/nouveau/threaded.c4
-rw-r--r--tests/planetest/Android.bp33
-rw-r--r--tests/planetest/Android.sources.bp24
-rw-r--r--tests/planetest/Makefile.am30
-rw-r--r--tests/planetest/Makefile.sources13
-rw-r--r--tests/planetest/atomictest.c151
-rw-r--r--tests/planetest/bo.c234
-rw-r--r--tests/planetest/bo.h34
-rw-r--r--tests/planetest/dev.c367
-rw-r--r--tests/planetest/dev.h65
-rw-r--r--tests/planetest/modeset.c232
-rw-r--r--tests/planetest/modeset.h19
-rw-r--r--tests/planetest/planetest.c116
-rw-r--r--tests/proptest/Makefile.am1
-rw-r--r--tests/proptest/meson.build28
-rw-r--r--tests/radeon/Makefile.am1
-rw-r--r--tests/radeon/meson.build27
-rw-r--r--tests/tegra/Makefile.am4
-rw-r--r--tests/tegra/meson.build27
-rw-r--r--tests/tegra/openclose.c4
-rw-r--r--tests/util/format.c4
-rw-r--r--tests/util/kms.c9
-rw-r--r--tests/util/meson.build28
-rw-r--r--tests/util/pattern.c19
-rw-r--r--tests/vbltest/Makefile.am1
-rw-r--r--tests/vbltest/meson.build28
-rw-r--r--tests/vbltest/vbltest.c4
-rw-r--r--util_math.h2
-rw-r--r--vc4/Makefile.am1
-rw-r--r--vc4/meson.build28
-rw-r--r--xf86atomic.h6
-rw-r--r--xf86drm.c863
-rw-r--r--xf86drm.h34
-rw-r--r--xf86drmHash.c27
-rw-r--r--xf86drmMode.c549
-rw-r--r--xf86drmMode.h52
-rw-r--r--xf86drmRandom.c9
-rw-r--r--xf86drmSL.c23
268 files changed, 14251 insertions, 7778 deletions
diff --git a/.editorconfig b/.editorconfig
index 893b7be0..29b4f393 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -17,3 +17,7 @@ indent_style = tab
[*.m4]
indent_style = space
indent_size = 2
+
+[{meson.build,meson_options.txt}]
+indent_style = space
+indent_size = 2
diff --git a/.gitignore b/.gitignore
index d51e619b..811348ab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,3 @@
-bsd-core/*/@
-bsd-core/*/machine
-*~
*.1
*.3
*.5
@@ -17,17 +14,22 @@ bsd-core/*/machine
*.o.cmd
*.sw?
*.trs
+*~
+.*check*
+.*install*
.depend
.deps
.libs
.tmp_versions
-.*check*
-.*install*
+/_build*
+/build*
Makefile
Makefile.in
TAGS
aclocal.m4
autom4te.cache
+bsd-core/*/@
+bsd-core/*/machine
build-aux
bus_if.h
compile
@@ -47,21 +49,22 @@ drm_pciids.h
export_syms
i915.kld
install-sh
-libdrm/config.h.in
libdrm.pc
+libdrm/config.h.in
+libdrm_amdgpu.pc
+libdrm_etnaviv.pc
+libdrm_exynos.pc
+libdrm_freedreno.pc
libdrm_intel.pc
libdrm_nouveau.pc
-libdrm_radeon.pc
libdrm_omap.pc
-libdrm_exynos.pc
-libdrm_freedreno.pc
-libdrm_amdgpu.pc
+libdrm_radeon.pc
libdrm_vc4.pc
-libdrm_etnaviv.pc
libkms.pc
libtool
ltmain.sh
mach64.kld
+man/*.3
man/.man_fixup
mga.kld
missing
@@ -74,35 +77,34 @@ savage.kld
sis.kld
stamp-h1
tdfx.kld
-via.kld
-tests/auth
tests/amdgpu/amdgpu_test
+tests/auth
tests/dristat
tests/drmdevice
tests/drmsl
tests/drmstat
+tests/etnaviv/etnaviv_2d_test
+tests/etnaviv/etnaviv_bo_cache_test
+tests/etnaviv/etnaviv_cmd_stream_test
+tests/exynos/exynos_fimg2d_event
+tests/exynos/exynos_fimg2d_perf
+tests/exynos/exynos_fimg2d_test
tests/getclient
tests/getstats
tests/getversion
tests/hash
+tests/kms/kms-steal-crtc
+tests/kms/kms-universal-planes
+tests/kmstest/kmstest
tests/lock
-tests/openclose
-tests/random
-tests/setversion
-tests/updatedraw
tests/modeprint/modeprint
tests/modetest/modetest
tests/name_from_fd
+tests/openclose
tests/proptest/proptest
-tests/kms/kms-steal-crtc
-tests/kms/kms-universal-planes
-tests/kmstest/kmstest
-tests/vbltest/vbltest
tests/radeon/radeon_ttm
-tests/exynos/exynos_fimg2d_event
-tests/exynos/exynos_fimg2d_perf
-tests/exynos/exynos_fimg2d_test
-tests/etnaviv/etnaviv_2d_test
-tests/etnaviv/etnaviv_cmd_stream_test
-tests/etnaviv/etnaviv_bo_cache_test
-man/*.3
+tests/random
+tests/setversion
+tests/updatedraw
+tests/vbltest/vbltest
+via.kld
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000..a0edfdff
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,159 @@
+.artifacts-meson: &artifacts-meson
+ when: always
+ paths:
+ - _build/meson-logs
+
+.artifacts-autotools: &artifacts-autotools
+ when: always
+ paths:
+ - _build/*.log
+ - _build/*/*.log
+ - _build/*/*/*.log
+
+.meson-build: &meson-build
+ - meson _build
+ -D amdgpu=true
+ -D cairo-tests=true
+ -D etnaviv=true
+ -D exynos=true
+ -D freedreno=true
+ -D freedreno-kgsl=true
+ -D intel=true
+ -D libkms=true
+ -D man-pages=true
+ -D nouveau=true
+ -D omap=true
+ -D radeon=true
+ -D tegra=true
+ -D udev=true
+ -D valgrind=true
+ -D vc4=true
+ -D vmwgfx=true
+ - ninja -C _build
+ - ninja -C _build test
+
+.autotools-build: &autotools-build
+ - mkdir _build
+ - cd _build
+ - ../autogen.sh
+ --enable-udev
+ --enable-libkms
+ --enable-intel
+ --enable-radeon
+ --enable-amdgpu
+ --enable-nouveau
+ --enable-vmwgfx
+ --enable-omap-experimental-api
+ --enable-exynos-experimental-api
+ --enable-freedreno
+ --enable-freedreno-kgsl
+ --enable-tegra-experimental-api
+ --enable-vc4
+ --enable-etnaviv-experimental-api
+ - make
+ - make check
+
+latest-meson:
+ stage: build
+ image: base/archlinux:latest
+ before_script:
+ - pacman -Syu --noconfirm --needed
+ base-devel
+ meson
+ libpciaccess
+ libxslt docbook-xsl
+ valgrind
+ libatomic_ops
+ cairo cunit
+ script: *meson-build
+
+latest-autotools:
+ stage: build
+ image: base/archlinux:latest
+ artifacts: *artifacts-autotools
+ before_script:
+ - pacman -Syu --noconfirm --needed
+ base-devel
+ libpciaccess
+ libxslt docbook-xsl
+ valgrind
+ libatomic_ops
+ cairo cunit
+ xorg-util-macros
+ git # autogen.sh depends on git
+ script: *autotools-build
+
+oldest-meson:
+ stage: build
+ image: debian:stable
+ artifacts: *artifacts-meson
+ before_script:
+ - printf > /etc/dpkg/dpkg.cfg.d/99-exclude-cruft "%s\n"
+ 'path-exclude=/usr/share/doc/*'
+ 'path-exclude=/usr/share/man/*'
+ - printf > /usr/sbin/policy-rc.d "%s\n"
+ '#!/bin/sh'
+ 'exit 101'
+ - chmod +x /usr/sbin/policy-rc.d
+ - apt-get update
+ - apt-get -y --no-install-recommends install
+ build-essential
+ pkg-config
+ xsltproc
+ libxslt1-dev docbook-xsl
+ valgrind
+ libatomic-ops-dev
+ libcairo2-dev libcunit1-dev
+ ninja-build
+ python3 python3-pip
+ wget
+ # We need `--no-check-certificate` here because Debian's CA list is
+ # too old to know about LetsEncrypt's CA, so it refuses to connect
+ # to FreeDesktop.org
+ - LIBPCIACCESS_VERSION=libpciaccess-0.10 &&
+ wget --no-check-certificate https://xorg.freedesktop.org/releases/individual/lib/$LIBPCIACCESS_VERSION.tar.bz2 &&
+ tar -jxvf $LIBPCIACCESS_VERSION.tar.bz2 &&
+ (cd $LIBPCIACCESS_VERSION && ./configure --prefix=$HOME/prefix && make install)
+ - pip3 install wheel setuptools
+ - pip3 install meson==0.43
+ - export PKG_CONFIG_PATH=$HOME/prefix/lib/pkgconfig:$HOME/prefix/share/pkgconfig
+ - export LD_LIBRARY_PATH="$HOME/prefix/lib:$LD_LIBRARY_PATH"
+ script: *meson-build
+
+oldest-autotools:
+ stage: build
+ image: debian:stable
+ artifacts: *artifacts-autotools
+ before_script:
+ - printf > /etc/dpkg/dpkg.cfg.d/99-exclude-cruft "%s\n"
+ 'path-exclude=/usr/share/doc/*'
+ 'path-exclude=/usr/share/man/*'
+ - printf > /usr/sbin/policy-rc.d "%s\n"
+ '#!/bin/sh'
+ 'exit 101'
+ - chmod +x /usr/sbin/policy-rc.d
+ - apt-get update
+ - apt-get -y --no-install-recommends install
+ build-essential
+ automake
+ autoconf
+ libtool
+ pkg-config
+ xsltproc
+ libxslt1-dev docbook-xsl
+ valgrind
+ libatomic-ops-dev
+ libcairo2-dev libcunit1-dev
+ wget
+ xutils-dev
+ git # autogen.sh depends on git
+ # We need `--no-check-certificate` here because Debian's CA list is
+ # too old to know about LetsEncrypt's CA, so it refuses to connect
+ # to FreeDesktop.org
+ - LIBPCIACCESS_VERSION=libpciaccess-0.10 &&
+ wget --no-check-certificate https://xorg.freedesktop.org/releases/individual/lib/$LIBPCIACCESS_VERSION.tar.bz2 &&
+ tar -jxvf $LIBPCIACCESS_VERSION.tar.bz2 &&
+ (cd $LIBPCIACCESS_VERSION && ./configure --prefix=$HOME/prefix && make install)
+ - export PKG_CONFIG_PATH=$HOME/prefix/lib/pkgconfig:$HOME/prefix/share/pkgconfig
+ - export LD_LIBRARY_PATH="$HOME/prefix/lib:$LD_LIBRARY_PATH"
+ script: *autotools-build
diff --git a/Android.bp b/Android.bp
index 429c22cc..9121068a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -54,7 +54,7 @@ cc_library {
"libdrm_sources",
],
- export_include_dirs: ["include/drm"],
+ export_include_dirs: ["include/drm", "android"],
cflags: [
"-Wno-enum-conversion",
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
new file mode 100644
index 00000000..96f1e4fb
--- /dev/null
+++ b/CONTRIBUTING.rst
@@ -0,0 +1,105 @@
+Contributing to libdrm
+======================
+
+Submitting Patches
+------------------
+
+Patches should be sent to dri-devel@lists.freedesktop.org, using git
+send-email. For patches only touching driver specific code one of the driver
+mailing lists (like amd-gfx@lists.freedesktop.org) is also appropriate. See git
+documentation for help:
+
+http://git-scm.com/documentation
+
+Since dri-devel is a very busy mailing list please use --subject-prefix="PATCH
+libdrm" to make it easier to find libdrm patches. This is best done by running
+
+ git config --local format.subjectprefix "PATCH libdrm"
+
+The first line of a commit message should contain a prefix indicating what part
+is affected by the patch followed by one sentence that describes the change. For
+examples:
+
+ amdgpu: Use uint32_t i in amdgpu_find_bo_by_cpu_mapping
+
+The body of the commit message should describe what the patch changes and why,
+and also note any particular side effects. For a recommended reading on
+writing commit messages, see:
+
+http://who-t.blogspot.de/2009/12/on-commit-messages.html
+
+Your patches should also include a Signed-off-by line with your name and email
+address. If you're not the patch's original author, you should also gather
+S-o-b's by them (and/or whomever gave the patch to you.) The significance of
+this is that it certifies that you created the patch, that it was created under
+an appropriate open source license, or provided to you under those terms. This
+lets us indicate a chain of responsibility for the copyright status of the code.
+For more details:
+
+https://developercertificate.org/
+
+We won't reject patches that lack S-o-b, but it is strongly recommended.
+
+Review and Merging
+------------------
+
+Patches should have at least one positive review (Reviewed-by: tag) or
+indication of approval (Acked-by: tag) before merging. For any code shared
+between drivers this is mandatory.
+
+Please note that kernel/userspace API header files have special rules, see
+include/drm/README.
+
+Coding style in the project loosely follows the CodingStyle of the linux kernel:
+
+https://www.kernel.org/doc/html/latest/process/coding-style.html?highlight=coding%20style
+
+Commit Rights
+-------------
+
+Commit rights will be granted to anyone who requests them and fulfills the
+below criteria:
+
+- Submitted a few (5-10 as a rule of thumb) non-trivial (not just simple
+ spelling fixes and whitespace adjustment) patches that have been merged
+ already. Since libdrm is just a glue library between the kernel and userspace
+ drivers, merged patches to those components also count towards the commit
+ criteria.
+
+- Are actively participating on discussions about their work (on the mailing
+ list or IRC). This should not be interpreted as a requirement to review other
+ peoples patches but just make sure that patch submission isn't one-way
+ communication. Cross-review is still highly encouraged.
+
+- Will be regularly contributing further patches. This includes regular
+ contributors to other parts of the open source graphics stack who only
+ do the oddball rare patch within libdrm itself.
+
+- Agrees to use their commit rights in accordance with the documented merge
+ criteria, tools, and processes.
+
+To apply for commit rights ("Developer" role in gitlab) send a mail to
+dri-devel@lists.freedesktop.org and please ping the maintainers if your request
+is stuck.
+
+Committers are encouraged to request their commit rights get removed when they
+no longer contribute to the project. Commit rights will be reinstated when they
+come back to the project.
+
+Maintainers and committers should encourage contributors to request commit
+rights, as especially junior contributors tend to underestimate their skills.
+
+Code of Conduct
+---------------
+
+Please be aware the fd.o Code of Conduct also applies to libdrm:
+
+https://www.freedesktop.org/wiki/CodeOfConduct/
+
+See the gitlab project owners for contact details of the libdrm maintainers.
+
+Abuse of commit rights, like engaging in commit fights or willfully pushing
+patches that violate the documented merge criteria, will also be handled through
+the Code of Conduct enforcement process.
+
+Happy hacking!
diff --git a/Makefile.am b/Makefile.am
index 2bf644be..730de1f2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,10 +96,6 @@ MAN_SUBDIR = man
endif
endif
-if HAVE_ROCKCHIP
-ROCKCHIP_SUBDIR = rockchip
-endif
-
SUBDIRS = \
. \
$(LIBKMS_SUBDIR) \
@@ -113,9 +109,9 @@ SUBDIRS = \
$(TEGRA_SUBDIR) \
$(VC4_SUBDIR) \
$(ETNAVIV_SUBDIR) \
+ data \
tests \
- $(MAN_SUBDIR) \
- $(ROCKCHIP_SUBDIR)
+ $(MAN_SUBDIR)
libdrm_la_LTLIBRARIES = libdrm.la
libdrm_ladir = $(libdir)
@@ -125,6 +121,7 @@ libdrm_la_LIBADD = @CLOCK_LIB@ -lm
libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
$(VALGRIND_CFLAGS)
libdrm_la_SOURCES = $(LIBDRM_FILES)
@@ -139,7 +136,37 @@ if HAVE_VMWGFX
klibdrminclude_HEADERS += $(LIBDRM_INCLUDE_VMWGFX_H_FILES)
endif
-EXTRA_DIST = include/drm/README
+EXTRA_DIST = \
+ include/drm/README \
+ amdgpu/meson.build \
+ data/meson.build \
+ etnaviv/meson.build \
+ exynos/meson.build \
+ freedreno/meson.build \
+ intel/meson.build \
+ libkms/meson.build \
+ man/meson.build \
+ nouveau/meson.build \
+ omap/meson.build \
+ radeon/meson.build \
+ tegra/meson.build \
+ tests/amdgpu/meson.build \
+ tests/etnaviv/meson.build \
+ tests/exynos/meson.build \
+ tests/kms/meson.build \
+ tests/kmstest/meson.build \
+ tests/meson.build \
+ tests/modeprint/meson.build \
+ tests/modetest/meson.build \
+ tests/nouveau/meson.build \
+ tests/proptest/meson.build \
+ tests/radeon/meson.build \
+ tests/tegra/meson.build \
+ tests/util/meson.build \
+ tests/vbltest/meson.build \
+ vc4/meson.build \
+ meson.build \
+ meson_options.txt
copy-headers :
cp -r $(kernel_source)/include/uapi/drm/*.h $(top_srcdir)/include/drm/
diff --git a/Makefile.sources b/Makefile.sources
index 10aa1d0f..55290fe9 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -25,6 +25,7 @@ LIBDRM_INCLUDE_H_FILES := \
include/drm/i915_drm.h \
include/drm/mach64_drm.h \
include/drm/mga_drm.h \
+ include/drm/msm_drm.h \
include/drm/nouveau_drm.h \
include/drm/qxl_drm.h \
include/drm/r128_drm.h \
@@ -37,5 +38,8 @@ LIBDRM_INCLUDE_H_FILES := \
include/drm/via_drm.h \
include/drm/virtgpu_drm.h
+LIBDRM_INCLUDE_ANDROID_H_FILES := \
+ android/gralloc_handle.h
+
LIBDRM_INCLUDE_VMWGFX_H_FILES := \
include/drm/vmwgfx_drm.h
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 00000000..7b4c82dc
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,5 @@
+# Default code reviewers picked from top 3 or more developers.
+# Please update this list if you find better candidates.
+adelva@google.com
+john.stultz@linaro.org
+seanpaul@google.com
diff --git a/README b/README
deleted file mode 100644
index 26cab9d3..00000000
--- a/README
+++ /dev/null
@@ -1,41 +0,0 @@
-libdrm - userspace library for drm
-
-This is libdrm, a userspace library for accessing the DRM, direct
-rendering manager, on Linux, BSD and other operating systems that
-support the ioctl interface. The library provides wrapper functions
-for the ioctls to avoid exposing the kernel interface directly, and
-for chipsets with drm memory manager, support for tracking relocations
-and buffers. libdrm is a low-level library, typically used by
-graphics drivers such as the Mesa DRI drivers, the X drivers, libva
-and similar projects. New functionality in the kernel DRM drivers
-typically requires a new libdrm, but a new libdrm will always work
-with an older kernel.
-
-
-Compiling
----------
-
-libdrm is a standard autotools package and follows the normal
-configure, build and install steps. The first step is to configure
-the package, which is done by running the configure shell script:
-
- ./configure
-
-By default, libdrm will install into the /usr/local/ prefix. If you
-want to install this DRM to replace your system copy, pass
---prefix=/usr and --exec-prefix=/ to configure. If you are building
-libdrm from a git checkout, you first need to run the autogen.sh
-script. You can pass any options to autogen.sh that you would other
-wise pass to configure, or you can just re-run configure with the
-options you need once autogen.sh finishes.
-
-Next step is to build libdrm:
-
- make
-
-and once make finishes successfully, install the package using
-
- make install
-
-If you are installing into a system location, you will need to be root
-to perform the install step.
diff --git a/README.rst b/README.rst
new file mode 100644
index 00000000..e47cb241
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,61 @@
+libdrm - userspace library for drm
+----------------------------------
+
+This is libdrm, a userspace library for accessing the DRM, direct rendering
+manager, on Linux, BSD and other operating systems that support the ioctl
+interface.
+The library provides wrapper functions for the ioctls to avoid exposing the
+kernel interface directly, and for chipsets with drm memory manager, support
+for tracking relocations and buffers.
+New functionality in the kernel DRM drivers typically requires a new libdrm,
+but a new libdrm will always work with an older kernel.
+
+libdrm is a low-level library, typically used by graphics drivers such as
+the Mesa drivers, the X drivers, libva and similar projects.
+
+
+Compiling
+---------
+
+libdrm has two build systems, a legacy autotools build system, and a newer
+meson build system. The meson build system is much faster, and offers a
+slightly different interface, but otherwise provides an equivalent feature set.
+
+To use it:
+
+ meson builddir/
+
+By default this will install into /usr/local, you can change your prefix
+with --prefix=/usr (or `meson configure builddir/ -Dprefix=/usr` after
+the initial meson setup).
+
+Then use ninja to build and install:
+
+ ninja -C builddir/ install
+
+If you are installing into a system location you will need to run install
+separately, and as root.
+
+
+Alternatively you can invoke autotools configure:
+
+ ./configure
+
+By default, libdrm will install into the /usr/local/ prefix. If you
+want to install this DRM to replace your system copy, pass
+--prefix=/usr and --exec-prefix=/ to configure. If you are building
+libdrm from a git checkout, you first need to run the autogen.sh
+script. You can pass any options to autogen.sh that you would other
+wise pass to configure, or you can just re-run configure with the
+options you need once autogen.sh finishes.
+
+Next step is to build libdrm:
+
+ make
+
+and once make finishes successfully, install the package using
+
+ make install
+
+If you are installing into a system location, you will need to be root
+to perform the install step.
diff --git a/RELEASING b/RELEASING
index 262ca08d..7e03e3b9 100644
--- a/RELEASING
+++ b/RELEASING
@@ -9,9 +9,9 @@ However, this is up to whoever is driving the feature in question.
Follow these steps to release a new version of libdrm:
- 1) Bump the version number in configure.ac. We seem to have settled
- for 2.4.x as the versioning scheme for libdrm, so just bump the
- micro version.
+ 1) Bump the version number in configure.ac and meson.build. We seem
+ to have settled for 2.4.x as the versioning scheme for libdrm, so
+ just bump the micro version.
2) Run autoconf and then re-run ./configure so the build system
picks up the new version number.
diff --git a/amdgpu/.editorconfig b/amdgpu/.editorconfig
new file mode 100644
index 00000000..426273fd
--- /dev/null
+++ b/amdgpu/.editorconfig
@@ -0,0 +1,13 @@
+# To use this config with your editor, follow the instructions at:
+# http://editorconfig.org
+
+[*]
+charset = utf-8
+indent_style = tab
+indent_size = 8
+tab_width = 8
+insert_final_newline = true
+
+[meson.build]
+indent_style = space
+indent_size = 2
diff --git a/amdgpu/Android.bp b/amdgpu/Android.bp
index a63b6174..976f03e9 100644
--- a/amdgpu/Android.bp
+++ b/amdgpu/Android.bp
@@ -2,6 +2,11 @@ build = ["Android.sources.bp"]
cc_library_shared {
name: "libdrm_amdgpu",
+
+ cflags: [
+ "-DAMDGPU_ASIC_ID_TABLE=\"/vendor/etc/hwdata/amdgpu.ids\""
+ ],
+
defaults: [
"libdrm_defaults",
"libdrm_amdgpu_sources",
diff --git a/amdgpu/Android.sources.bp b/amdgpu/Android.sources.bp
index 62b8f054..be85283d 100644
--- a/amdgpu/Android.sources.bp
+++ b/amdgpu/Android.sources.bp
@@ -3,12 +3,13 @@
cc_defaults {
name: "libdrm_amdgpu_sources",
srcs: [
+ "amdgpu_asic_id.c",
"amdgpu_bo.c",
"amdgpu_cs.c",
"amdgpu_device.c",
"amdgpu_gpu_info.c",
"amdgpu_vamgr.c",
- "util_hash.c",
- "util_hash_table.c",
+ "amdgpu_vm.c",
+ "handle_table.c",
],
}
diff --git a/amdgpu/Makefile.am b/amdgpu/Makefile.am
index cf7bc1ba..ef8ab057 100644
--- a/amdgpu/Makefile.am
+++ b/amdgpu/Makefile.am
@@ -26,16 +26,21 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
+libdrmdatadir = @libdrmdatadir@
+AM_CPPFLAGS = -DAMDGPU_ASIC_ID_TABLE=\"${libdrmdatadir}/amdgpu.ids\"
+
libdrm_amdgpu_la_LTLIBRARIES = libdrm_amdgpu.la
libdrm_amdgpu_ladir = $(libdir)
libdrm_amdgpu_la_LDFLAGS = -version-number 1:0:0 -no-undefined
libdrm_amdgpu_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
libdrm_amdgpu_la_SOURCES = $(LIBDRM_AMDGPU_FILES)
+amdgpu_asic_id.lo: $(top_srcdir)/data/amdgpu.ids
libdrm_amdgpuincludedir = ${includedir}/libdrm
libdrm_amdgpuinclude_HEADERS = $(LIBDRM_AMDGPU_H_FILES)
@@ -43,5 +48,6 @@ libdrm_amdgpuinclude_HEADERS = $(LIBDRM_AMDGPU_H_FILES)
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_amdgpu.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = amdgpu-symbol-check
EXTRA_DIST = $(TESTS)
diff --git a/amdgpu/Makefile.sources b/amdgpu/Makefile.sources
index 487b9e0a..d6df324a 100644
--- a/amdgpu/Makefile.sources
+++ b/amdgpu/Makefile.sources
@@ -1,15 +1,14 @@
LIBDRM_AMDGPU_FILES := \
- amdgpu_asic_id.h \
+ amdgpu_asic_id.c \
amdgpu_bo.c \
amdgpu_cs.c \
amdgpu_device.c \
amdgpu_gpu_info.c \
amdgpu_internal.h \
amdgpu_vamgr.c \
- util_hash.c \
- util_hash.h \
- util_hash_table.c \
- util_hash_table.h
+ amdgpu_vm.c \
+ handle_table.c \
+ handle_table.h
LIBDRM_AMDGPU_H_FILES := \
amdgpu.h
diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 87f4fd2c..96a44b40 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -1,9 +1,11 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.am/libdrm_amdgpuinclude_HEADERS
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_amdgpu.so} | awk '{print $3}' | while read func; do
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_amdgpu.so} | awk '{print $3}' | while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
__bss_start
_edata
@@ -16,25 +18,48 @@ amdgpu_bo_cpu_unmap
amdgpu_bo_export
amdgpu_bo_free
amdgpu_bo_import
+amdgpu_bo_inc_ref
+amdgpu_bo_list_create_raw
+amdgpu_bo_list_destroy_raw
amdgpu_bo_list_create
amdgpu_bo_list_destroy
amdgpu_bo_list_update
amdgpu_bo_query_info
amdgpu_bo_set_metadata
amdgpu_bo_va_op
+amdgpu_bo_va_op_raw
amdgpu_bo_wait_for_idle
amdgpu_create_bo_from_user_mem
+amdgpu_cs_chunk_fence_info_to_data
+amdgpu_cs_chunk_fence_to_dep
amdgpu_cs_create_semaphore
+amdgpu_cs_create_syncobj
+amdgpu_cs_create_syncobj2
amdgpu_cs_ctx_create
+amdgpu_cs_ctx_create2
amdgpu_cs_ctx_free
amdgpu_cs_destroy_semaphore
+amdgpu_cs_destroy_syncobj
+amdgpu_cs_export_syncobj
+amdgpu_cs_fence_to_handle
+amdgpu_cs_import_syncobj
amdgpu_cs_query_fence_status
amdgpu_cs_query_reset_state
+amdgpu_query_sw_info
amdgpu_cs_signal_semaphore
amdgpu_cs_submit
+amdgpu_cs_submit_raw
+amdgpu_cs_submit_raw2
+amdgpu_cs_syncobj_export_sync_file
+amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_reset
+amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_wait
+amdgpu_cs_wait_fences
amdgpu_cs_wait_semaphore
amdgpu_device_deinitialize
amdgpu_device_initialize
+amdgpu_find_bo_by_cpu_mapping
amdgpu_get_marketing_name
amdgpu_query_buffer_size_alignment
amdgpu_query_crtc_from_id
@@ -45,10 +70,13 @@ amdgpu_query_heap_info
amdgpu_query_hw_ip_count
amdgpu_query_hw_ip_info
amdgpu_query_info
+amdgpu_query_sensor_info
amdgpu_read_mm_registers
amdgpu_va_range_alloc
amdgpu_va_range_free
amdgpu_va_range_query
+amdgpu_vm_reserve_vmid
+amdgpu_vm_unreserve_vmid
EOF
done)
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 7b26a04c..d6de3b8d 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -37,7 +37,12 @@
#include <stdint.h>
#include <stdbool.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct drm_amdgpu_info_hw_ip;
+struct drm_amdgpu_bo_list_entry;
/*--------------------------------------------------------------------------*/
/* --------------------------- Defines ------------------------------------ */
@@ -80,7 +85,12 @@ enum amdgpu_bo_handle_type {
amdgpu_bo_handle_type_kms = 1,
/** DMA-buf fd handle */
- amdgpu_bo_handle_type_dma_buf_fd = 2
+ amdgpu_bo_handle_type_dma_buf_fd = 2,
+
+ /** KMS handle, but re-importing as a DMABUF handle through
+ * drmPrimeHandleToFD is forbidden. (Glamor does that)
+ */
+ amdgpu_bo_handle_type_kms_noimport = 3,
};
/** Define known types of GPU VM VA ranges */
@@ -90,6 +100,10 @@ enum amdgpu_gpu_va_range
amdgpu_gpu_va_range_general = 0
};
+enum amdgpu_sw_info {
+ amdgpu_sw_info_address32_hi = 0,
+};
+
/*--------------------------------------------------------------------------*/
/* -------------------------- Datatypes ----------------------------------- */
/*--------------------------------------------------------------------------*/
@@ -665,6 +679,29 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
amdgpu_bo_handle *buf_handle);
/**
+ * Validate if the user memory comes from BO
+ *
+ * \param dev - [in] Device handle. See #amdgpu_device_initialize()
+ * \param cpu - [in] CPU address of user allocated memory which we
+ * want to map to GPU address space (make GPU accessible)
+ * (This address must be correctly aligned).
+ * \param size - [in] Size of allocation (must be correctly aligned)
+ * \param buf_handle - [out] Buffer handle for the userptr memory
+ * if the user memory is not from BO, the buf_handle will be NULL.
+ * \param offset_in_bo - [out] offset in this BO for this user memory
+ *
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle dev,
+ void *cpu,
+ uint64_t size,
+ amdgpu_bo_handle *buf_handle,
+ uint64_t *offset_in_bo);
+
+/**
* Free previosuly allocated memory
*
* \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
@@ -685,7 +722,17 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
int amdgpu_bo_free(amdgpu_bo_handle buf_handle);
/**
- * Request CPU access to GPU accessible memory
+ * Increase the reference count of a buffer object
+ *
+ * \param bo - \c [in] Buffer object handle to increase the reference count
+ *
+ * \sa amdgpu_bo_alloc(), amdgpu_bo_free()
+ *
+*/
+void amdgpu_bo_inc_ref(amdgpu_bo_handle bo);
+
+/**
+ * Request CPU access to GPU accessable memory
*
* \param buf_handle - \c [in] Buffer handle
* \param cpu - \c [out] CPU address to be used for access
@@ -733,6 +780,37 @@ int amdgpu_bo_wait_for_idle(amdgpu_bo_handle buf_handle,
*
* \param dev - \c [in] Device handle.
* See #amdgpu_device_initialize()
+ * \param number_of_buffers - \c [in] Number of BOs in the list
+ * \param buffers - \c [in] List of BO handles
+ * \param result - \c [out] Created BO list handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ * \sa amdgpu_bo_list_destroy_raw(), amdgpu_cs_submit_raw2()
+*/
+int amdgpu_bo_list_create_raw(amdgpu_device_handle dev,
+ uint32_t number_of_buffers,
+ struct drm_amdgpu_bo_list_entry *buffers,
+ uint32_t *result);
+
+/**
+ * Destroys a BO list handle.
+ *
+ * \param bo_list - \c [in] BO list handle.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ * \sa amdgpu_bo_list_create_raw(), amdgpu_cs_submit_raw2()
+*/
+int amdgpu_bo_list_destroy_raw(amdgpu_device_handle dev, uint32_t bo_list);
+
+/**
+ * Creates a BO list handle for command submission.
+ *
+ * \param dev - \c [in] Device handle.
+ * See #amdgpu_device_initialize()
* \param number_of_resources - \c [in] Number of BOs in the list
* \param resources - \c [in] List of BO handles
* \param resource_prios - \c [in] Optional priority for each handle
@@ -794,8 +872,9 @@ int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
* context will always be executed in order (first come, first serve).
*
*
- * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
- * \param context - \c [out] GPU Context handle
+ * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
+ * \param priority - \c [in] Context creation flags. See AMDGPU_CTX_PRIORITY_*
+ * \param context - \c [out] GPU Context handle
*
* \return 0 on success\n
* <0 - Negative POSIX Error code
@@ -803,6 +882,18 @@ int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
* \sa amdgpu_cs_ctx_free()
*
*/
+int amdgpu_cs_ctx_create2(amdgpu_device_handle dev,
+ uint32_t priority,
+ amdgpu_context_handle *context);
+/**
+ * Create GPU execution Context
+ *
+ * Refer to amdgpu_cs_ctx_create2 for full documentation. This call
+ * is missing the priority parameter.
+ *
+ * \sa amdgpu_cs_ctx_create2()
+ *
+*/
int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
amdgpu_context_handle *context);
@@ -907,6 +998,29 @@ int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence,
uint64_t flags,
uint32_t *expired);
+/**
+ * Wait for multiple fences
+ *
+ * \param fences - \c [in] The fence array to wait
+ * \param fence_count - \c [in] The fence count
+ * \param wait_all - \c [in] If true, wait all fences to be signaled,
+ * otherwise, wait at least one fence
+ * \param timeout_ns - \c [in] The timeout to wait, in nanoseconds
+ * \param status - \c [out] '1' for signaled, '0' for timeout
+ * \param first - \c [out] the index of the first signaled fence from @fences
+ *
+ * \return 0 on success
+ * <0 - Negative POSIX Error code
+ *
+ * \note Currently it supports only one amdgpu_device. All fences come from
+ * the same amdgpu_device with the same fd.
+*/
+int amdgpu_cs_wait_fences(struct amdgpu_cs_fence *fences,
+ uint32_t fence_count,
+ bool wait_all,
+ uint64_t timeout_ns,
+ uint32_t *status, uint32_t *first);
+
/*
* Query / Info API
*
@@ -1046,6 +1160,23 @@ int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
unsigned size, void *value);
/**
+ * Query hardware or driver information.
+ *
+ * The return size is query-specific and depends on the "info_id" parameter.
+ * No more than "size" bytes is returned.
+ *
+ * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
+ * \param info - \c [in] amdgpu_sw_info_*
+ * \param value - \c [out] Pointer to the return value.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX error code
+ *
+*/
+int amdgpu_query_sw_info(amdgpu_device_handle dev, enum amdgpu_sw_info info,
+ void *value);
+
+/**
* Query information about GDS
*
* \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
@@ -1059,6 +1190,24 @@ int amdgpu_query_gds_info(amdgpu_device_handle dev,
struct amdgpu_gds_resource_info *gds_info);
/**
+ * Query information about sensor.
+ *
+ * The return size is query-specific and depends on the "sensor_type"
+ * parameter. No more than "size" bytes is returned.
+ *
+ * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
+ * \param sensor_type - \c [in] AMDGPU_INFO_SENSOR_*
+ * \param size - \c [in] Size of the returned value.
+ * \param value - \c [out] Pointer to the return value.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
+ unsigned size, void *value);
+
+/**
* Read a set of consecutive memory-mapped registers.
* Not all registers are allowed to be read by userspace.
*
@@ -1083,6 +1232,7 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset,
* Flag to request VA address range in the 32bit address space
*/
#define AMDGPU_VA_RANGE_32_BIT 0x1
+#define AMDGPU_VA_RANGE_HIGH 0x2
/**
* Allocate virtual address range
@@ -1186,6 +1336,34 @@ int amdgpu_bo_va_op(amdgpu_bo_handle bo,
uint32_t ops);
/**
+ * VA mapping/unmapping for a buffer object or PRT region.
+ *
+ * This is not a simple drop-in extension for amdgpu_bo_va_op; instead, all
+ * parameters are treated "raw", i.e. size is not automatically aligned, and
+ * all flags must be specified explicitly.
+ *
+ * \param dev - \c [in] device handle
+ * \param bo - \c [in] BO handle (may be NULL)
+ * \param offset - \c [in] Start offset to map
+ * \param size - \c [in] Size to map
+ * \param addr - \c [in] Start virtual address.
+ * \param flags - \c [in] Supported flags for mapping/unmapping
+ * \param ops - \c [in] AMDGPU_VA_OP_MAP or AMDGPU_VA_OP_UNMAP
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+
+int amdgpu_bo_va_op_raw(amdgpu_device_handle dev,
+ amdgpu_bo_handle bo,
+ uint64_t offset,
+ uint64_t size,
+ uint64_t addr,
+ uint64_t flags,
+ uint32_t ops);
+
+/**
* create semaphore
*
* \param sem - \c [out] semaphore handle
@@ -1255,4 +1433,238 @@ int amdgpu_cs_destroy_semaphore(amdgpu_semaphore_handle sem);
*/
const char *amdgpu_get_marketing_name(amdgpu_device_handle dev);
+/**
+ * Create kernel sync object
+ *
+ * \param dev - \c [in] device handle
+ * \param flags - \c [in] flags that affect creation
+ * \param syncobj - \c [out] sync object handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_create_syncobj2(amdgpu_device_handle dev,
+ uint32_t flags,
+ uint32_t *syncobj);
+
+/**
+ * Create kernel sync object
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [out] sync object handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_create_syncobj(amdgpu_device_handle dev,
+ uint32_t *syncobj);
+/**
+ * Destroy kernel sync object
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_destroy_syncobj(amdgpu_device_handle dev,
+ uint32_t syncobj);
+
+/**
+ * Reset kernel sync objects to unsignalled state.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobjs - \c [in] array of sync object handles
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
+ const uint32_t *syncobjs, uint32_t syncobj_count);
+
+/**
+ * Signal kernel sync objects.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobjs - \c [in] array of sync object handles
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs, uint32_t syncobj_count);
+
+/**
+ * Wait for one or all sync objects to signal.
+ *
+ * \param dev - \c [in] self-explanatory
+ * \param handles - \c [in] array of sync object handles
+ * \param num_handles - \c [in] self-explanatory
+ * \param timeout_nsec - \c [in] self-explanatory
+ * \param flags - \c [in] a bitmask of DRM_SYNCOBJ_WAIT_FLAGS_*
+ * \param first_signaled - \c [in] self-explanatory
+ *
+ * \return 0 on success\n
+ * -ETIME - Timeout
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
+ uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+
+/**
+ * Export kernel sync object to shareable fd.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ * \param shared_fd - \c [out] shared file descriptor.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int *shared_fd);
+/**
+ * Import kernel sync object from shareable fd.
+ *
+ * \param dev - \c [in] device handle
+ * \param shared_fd - \c [in] shared file descriptor.
+ * \param syncobj - \c [out] sync object handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_import_syncobj(amdgpu_device_handle dev,
+ int shared_fd,
+ uint32_t *syncobj);
+
+/**
+ * Export kernel sync object to a sync_file.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ * \param sync_file_fd - \c [out] sync_file file descriptor.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int *sync_file_fd);
+
+/**
+ * Import kernel sync object from a sync_file.
+ *
+ * \param dev - \c [in] device handle
+ * \param syncobj - \c [in] sync object handle
+ * \param sync_file_fd - \c [in] sync_file file descriptor.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int sync_file_fd);
+
+/**
+ * Export an amdgpu fence as a handle (syncobj or fd).
+ *
+ * \param what AMDGPU_FENCE_TO_HANDLE_GET_{SYNCOBJ, FD}
+ * \param out_handle returned handle
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ */
+int amdgpu_cs_fence_to_handle(amdgpu_device_handle dev,
+ struct amdgpu_cs_fence *fence,
+ uint32_t what,
+ uint32_t *out_handle);
+
+/**
+ * Submit raw command submission to kernel
+ *
+ * \param dev - \c [in] device handle
+ * \param context - \c [in] context handle for context id
+ * \param bo_list_handle - \c [in] request bo list handle (0 for none)
+ * \param num_chunks - \c [in] number of CS chunks to submit
+ * \param chunks - \c [in] array of CS chunks
+ * \param seq_no - \c [out] output sequence number for submission.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ */
+struct drm_amdgpu_cs_chunk;
+struct drm_amdgpu_cs_chunk_dep;
+struct drm_amdgpu_cs_chunk_data;
+
+int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
+ amdgpu_context_handle context,
+ amdgpu_bo_list_handle bo_list_handle,
+ int num_chunks,
+ struct drm_amdgpu_cs_chunk *chunks,
+ uint64_t *seq_no);
+
+/**
+ * Submit raw command submission to the kernel with a raw BO list handle.
+ *
+ * \param dev - \c [in] device handle
+ * \param context - \c [in] context handle for context id
+ * \param bo_list_handle - \c [in] raw bo list handle (0 for none)
+ * \param num_chunks - \c [in] number of CS chunks to submit
+ * \param chunks - \c [in] array of CS chunks
+ * \param seq_no - \c [out] output sequence number for submission.
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ * \sa amdgpu_bo_list_create_raw(), amdgpu_bo_list_destroy_raw()
+ */
+int amdgpu_cs_submit_raw2(amdgpu_device_handle dev,
+ amdgpu_context_handle context,
+ uint32_t bo_list_handle,
+ int num_chunks,
+ struct drm_amdgpu_cs_chunk *chunks,
+ uint64_t *seq_no);
+
+void amdgpu_cs_chunk_fence_to_dep(struct amdgpu_cs_fence *fence,
+ struct drm_amdgpu_cs_chunk_dep *dep);
+void amdgpu_cs_chunk_fence_info_to_data(struct amdgpu_cs_fence_info *fence_info,
+ struct drm_amdgpu_cs_chunk_data *data);
+
+/**
+ * Reserve VMID
+ * \param context - \c [in] GPU Context
+ * \param flags - \c [in] TBD
+ *
+ * \return 0 on success otherwise POSIX Error code
+*/
+int amdgpu_vm_reserve_vmid(amdgpu_device_handle dev, uint32_t flags);
+
+/**
+ * Free reserved VMID
+ * \param context - \c [in] GPU Context
+ * \param flags - \c [in] TBD
+ *
+ * \return 0 on success otherwise POSIX Error code
+*/
+int amdgpu_vm_unreserve_vmid(amdgpu_device_handle dev, uint32_t flags);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* #ifdef _AMDGPU_H_ */
diff --git a/amdgpu/amdgpu_asic_id.c b/amdgpu/amdgpu_asic_id.c
new file mode 100644
index 00000000..a5007ffc
--- /dev/null
+++ b/amdgpu/amdgpu_asic_id.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 2017 Advanced Micro Devices, Inc.
+ * 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, 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 <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "xf86drm.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+static int parse_one_line(struct amdgpu_device *dev, const char *line)
+{
+ char *buf, *saveptr;
+ char *s_did;
+ uint32_t did;
+ char *s_rid;
+ uint32_t rid;
+ char *s_name;
+ char *endptr;
+ int r = -EINVAL;
+
+ /* ignore empty line and commented line */
+ if (strlen(line) == 0 || line[0] == '#')
+ return -EAGAIN;
+
+ buf = strdup(line);
+ if (!buf)
+ return -ENOMEM;
+
+ /* device id */
+ s_did = strtok_r(buf, ",", &saveptr);
+ if (!s_did)
+ goto out;
+
+ did = strtol(s_did, &endptr, 16);
+ if (*endptr)
+ goto out;
+
+ if (did != dev->info.asic_id) {
+ r = -EAGAIN;
+ goto out;
+ }
+
+ /* revision id */
+ s_rid = strtok_r(NULL, ",", &saveptr);
+ if (!s_rid)
+ goto out;
+
+ rid = strtol(s_rid, &endptr, 16);
+ if (*endptr)
+ goto out;
+
+ if (rid != dev->info.pci_rev_id) {
+ r = -EAGAIN;
+ goto out;
+ }
+
+ /* marketing name */
+ s_name = strtok_r(NULL, ",", &saveptr);
+ if (!s_name)
+ goto out;
+
+ /* trim leading whitespaces or tabs */
+ while (isblank(*s_name))
+ s_name++;
+ if (strlen(s_name) == 0)
+ goto out;
+
+ dev->marketing_name = strdup(s_name);
+ if (dev->marketing_name)
+ r = 0;
+ else
+ r = -ENOMEM;
+
+out:
+ free(buf);
+
+ return r;
+}
+
+void amdgpu_parse_asic_ids(struct amdgpu_device *dev)
+{
+ FILE *fp;
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t n;
+ int line_num = 1;
+ int r = 0;
+
+ fp = fopen(AMDGPU_ASIC_ID_TABLE, "r");
+ if (!fp) {
+ fprintf(stderr, "%s: %s\n", AMDGPU_ASIC_ID_TABLE,
+ strerror(errno));
+ return;
+ }
+
+ /* 1st valid line is file version */
+ while ((n = getline(&line, &len, fp)) != -1) {
+ /* trim trailing newline */
+ if (line[n - 1] == '\n')
+ line[n - 1] = '\0';
+
+ /* ignore empty line and commented line */
+ if (strlen(line) == 0 || line[0] == '#') {
+ line_num++;
+ continue;
+ }
+
+ drmMsg("%s version: %s\n", AMDGPU_ASIC_ID_TABLE, line);
+ break;
+ }
+
+ while ((n = getline(&line, &len, fp)) != -1) {
+ /* trim trailing newline */
+ if (line[n - 1] == '\n')
+ line[n - 1] = '\0';
+
+ r = parse_one_line(dev, line);
+ if (r != -EAGAIN)
+ break;
+
+ line_num++;
+ }
+
+ if (r == -EINVAL) {
+ fprintf(stderr, "Invalid format: %s: line %d: %s\n",
+ AMDGPU_ASIC_ID_TABLE, line_num, line);
+ } else if (r && r != -EAGAIN) {
+ fprintf(stderr, "%s: Cannot parse ASIC IDs: %s\n",
+ __func__, strerror(-r));
+ }
+
+ free(line);
+ fclose(fp);
+}
diff --git a/amdgpu/amdgpu_asic_id.h b/amdgpu/amdgpu_asic_id.h
deleted file mode 100644
index 3e7d736b..00000000
--- a/amdgpu/amdgpu_asic_id.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright © 2016 Advanced Micro Devices, Inc.
- * 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, 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 __AMDGPU_ASIC_ID_H__
-#define __AMDGPU_ASIC_ID_H__
-
-static struct amdgpu_asic_id_table_t {
- uint32_t did;
- uint32_t rid;
- const char *marketing_name;
-} const amdgpu_asic_id_table [] = {
- {0x6600, 0x0, "AMD Radeon HD 8600/8700M"},
- {0x6600, 0x81, "AMD Radeon R7 M370"},
- {0x6601, 0x0, "AMD Radeon HD 8500M/8700M"},
- {0x6604, 0x0, "AMD Radeon R7 M265 Series"},
- {0x6604, 0x81, "AMD Radeon R7 M350"},
- {0x6605, 0x0, "AMD Radeon R7 M260 Series"},
- {0x6605, 0x81, "AMD Radeon R7 M340"},
- {0x6606, 0x0, "AMD Radeon HD 8790M"},
- {0x6607, 0x0, "AMD Radeon HD8530M"},
- {0x6608, 0x0, "AMD FirePro W2100"},
- {0x6610, 0x0, "AMD Radeon HD 8600 Series"},
- {0x6610, 0x81, "AMD Radeon R7 350"},
- {0x6610, 0x83, "AMD Radeon R5 340"},
- {0x6611, 0x0, "AMD Radeon HD 8500 Series"},
- {0x6613, 0x0, "AMD Radeon HD 8500 series"},
- {0x6617, 0xC7, "AMD Radeon R7 240 Series"},
- {0x6640, 0x0, "AMD Radeon HD 8950"},
- {0x6640, 0x80, "AMD Radeon R9 M380"},
- {0x6646, 0x0, "AMD Radeon R9 M280X"},
- {0x6646, 0x80, "AMD Radeon R9 M470X"},
- {0x6647, 0x0, "AMD Radeon R9 M270X"},
- {0x6647, 0x80, "AMD Radeon R9 M380"},
- {0x6649, 0x0, "AMD FirePro W5100"},
- {0x6658, 0x0, "AMD Radeon R7 200 Series"},
- {0x665C, 0x0, "AMD Radeon HD 7700 Series"},
- {0x665D, 0x0, "AMD Radeon R7 200 Series"},
- {0x665F, 0x81, "AMD Radeon R7 300 Series"},
- {0x6660, 0x0, "AMD Radeon HD 8600M Series"},
- {0x6660, 0x81, "AMD Radeon R5 M335"},
- {0x6660, 0x83, "AMD Radeon R5 M330"},
- {0x6663, 0x0, "AMD Radeon HD 8500M Series"},
- {0x6663, 0x83, "AMD Radeon R5 M320"},
- {0x6664, 0x0, "AMD Radeon R5 M200 Series"},
- {0x6665, 0x0, "AMD Radeon R5 M200 Series"},
- {0x6665, 0x83, "AMD Radeon R5 M320"},
- {0x6667, 0x0, "AMD Radeon R5 M200 Series"},
- {0x666F, 0x0, "AMD Radeon HD 8500M"},
- {0x6780, 0x0, "ATI FirePro V (FireGL V) Graphics Adapter"},
- {0x678A, 0x0, "ATI FirePro V (FireGL V) Graphics Adapter"},
- {0x6798, 0x0, "AMD Radeon HD 7900 Series"},
- {0x679A, 0x0, "AMD Radeon HD 7900 Series"},
- {0x679B, 0x0, "AMD Radeon HD 7900 Series"},
- {0x679E, 0x0, "AMD Radeon HD 7800 Series"},
- {0x67A0, 0x0, "HAWAII XTGL (67A0)"},
- {0x67A1, 0x0, "HAWAII GL40 (67A1)"},
- {0x67B0, 0x0, "AMD Radeon R9 200 Series"},
- {0x67B0, 0x80, "AMD Radeon R9 390 Series"},
- {0x67B1, 0x0, "AMD Radeon R9 200 Series"},
- {0x67B1, 0x80, "AMD Radeon R9 390 Series"},
- {0x67B9, 0x0, "AMD Radeon R9 200 Series"},
- {0x67DF, 0xC4, "AMD Radeon RX 480 Graphics"},
- {0x67DF, 0xC5, "AMD Radeon RX 470 Graphics"},
- {0x67DF, 0xC7, "AMD Radeon RX 480 Graphics"},
- {0x67DF, 0xCF, "AMD Radeon RX 470 Graphics"},
- {0x67C4, 0x00, "AMD Radeon Pro WX 7100 Graphics"},
- {0x67C7, 0x00, "AMD Radeon Pro WX 5100 Graphics"},
- {0x67C0, 0x00, "AMD Radeon Pro WX 7100 Graphics"},
- {0x67E0, 0x00, "AMD Radeon Pro WX Series Graphics"},
- {0x67E3, 0x00, "AMD Radeon Pro WX 4100 Graphics"},
- {0x67E8, 0x00, "AMD Radeon Pro WX Series Graphics"},
- {0x67E8, 0x01, "AMD Radeon Pro WX Series Graphics"},
- {0x67E8, 0x80, "AMD Radeon E9260 Graphics"},
- {0x67EB, 0x00, "AMD Radeon Pro WX Series Graphics"},
- {0x67EF, 0xC0, "AMD Radeon RX Graphics"},
- {0x67EF, 0xC1, "AMD Radeon RX 460 Graphics"},
- {0x67EF, 0xC5, "AMD Radeon RX 460 Graphics"},
- {0x67EF, 0xC7, "AMD Radeon RX Graphics"},
- {0x67EF, 0xCF, "AMD Radeon RX 460 Graphics"},
- {0x67EF, 0xEF, "AMD Radeon RX Graphics"},
- {0x67FF, 0xC0, "AMD Radeon RX Graphics"},
- {0x67FF, 0xC1, "AMD Radeon RX Graphics"},
- {0x6800, 0x0, "AMD Radeon HD 7970M"},
- {0x6801, 0x0, "AMD Radeon(TM) HD8970M"},
- {0x6808, 0x0, "ATI FirePro V(FireGL V) Graphics Adapter"},
- {0x6809, 0x0, "ATI FirePro V(FireGL V) Graphics Adapter"},
- {0x6810, 0x0, "AMD Radeon(TM) HD 8800 Series"},
- {0x6810, 0x81, "AMD Radeon R7 370 Series"},
- {0x6811, 0x0, "AMD Radeon(TM) HD8800 Series"},
- {0x6811, 0x81, "AMD Radeon R7 300 Series"},
- {0x6818, 0x0, "AMD Radeon HD 7800 Series"},
- {0x6819, 0x0, "AMD Radeon HD 7800 Series"},
- {0x6820, 0x0, "AMD Radeon HD 8800M Series"},
- {0x6820, 0x81, "AMD Radeon R9 M375"},
- {0x6820, 0x83, "AMD Radeon R9 M375X"},
- {0x6821, 0x0, "AMD Radeon HD 8800M Series"},
- {0x6821, 0x87, "AMD Radeon R7 M380"},
- {0x6821, 0x83, "AMD Radeon R9 M370X"},
- {0x6822, 0x0, "AMD Radeon E8860"},
- {0x6823, 0x0, "AMD Radeon HD 8800M Series"},
- {0x6825, 0x0, "AMD Radeon HD 7800M Series"},
- {0x6827, 0x0, "AMD Radeon HD 7800M Series"},
- {0x6828, 0x0, "ATI FirePro V(FireGL V) Graphics Adapter"},
- {0x682B, 0x0, "AMD Radeon HD 8800M Series"},
- {0x682B, 0x87, "AMD Radeon R9 M360"},
- {0x682C, 0x0, "AMD FirePro W4100"},
- {0x682D, 0x0, "AMD Radeon HD 7700M Series"},
- {0x682F, 0x0, "AMD Radeon HD 7700M Series"},
- {0x6835, 0x0, "AMD Radeon R7 Series / HD 9000 Series"},
- {0x6837, 0x0, "AMD Radeon HD7700 Series"},
- {0x683D, 0x0, "AMD Radeon HD 7700 Series"},
- {0x683F, 0x0, "AMD Radeon HD 7700 Series"},
- {0x6900, 0x0, "AMD Radeon R7 M260"},
- {0x6900, 0x81, "AMD Radeon R7 M360"},
- {0x6900, 0x83, "AMD Radeon R7 M340"},
- {0x6901, 0x0, "AMD Radeon R5 M255"},
- {0x6907, 0x0, "AMD Radeon R5 M255"},
- {0x6907, 0x87, "AMD Radeon R5 M315"},
- {0x6920, 0x0, "AMD Radeon R9 M395X"},
- {0x6920, 0x1, "AMD Radeon R9 M390X"},
- {0x6921, 0x0, "AMD Radeon R9 M295X"},
- {0x6929, 0x0, "AMD FirePro S7150"},
- {0x692B, 0x0, "AMD FirePro W7100"},
- {0x6938, 0x0, "AMD Radeon R9 200 Series"},
- {0x6938, 0xF0, "AMD Radeon R9 200 Series"},
- {0x6938, 0xF1, "AMD Radeon R9 380 Series"},
- {0x6939, 0xF0, "AMD Radeon R9 200 Series"},
- {0x6939, 0x0, "AMD Radeon R9 200 Series"},
- {0x6939, 0xF1, "AMD Radeon R9 380 Series"},
- {0x7300, 0xC8, "AMD Radeon R9 Fury Series"},
- {0x7300, 0xCB, "AMD Radeon R9 Fury Series"},
- {0x7300, 0xCA, "AMD Radeon R9 Fury Series"},
- {0x9874, 0xC4, "AMD Radeon R7 Graphics"},
- {0x9874, 0xC5, "AMD Radeon R6 Graphics"},
- {0x9874, 0xC6, "AMD Radeon R6 Graphics"},
- {0x9874, 0xC7, "AMD Radeon R5 Graphics"},
- {0x9874, 0x81, "AMD Radeon R6 Graphics"},
- {0x9874, 0x87, "AMD Radeon R5 Graphics"},
- {0x9874, 0x85, "AMD Radeon R6 Graphics"},
- {0x9874, 0x84, "AMD Radeon R7 Graphics"},
-
- {0x0000, 0x0, "\0"},
-};
-#endif
diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c
index d30fd1e7..32ee358f 100644
--- a/amdgpu/amdgpu_bo.c
+++ b/amdgpu/amdgpu_bo.c
@@ -22,10 +22,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
@@ -41,7 +37,6 @@
#include "xf86drm.h"
#include "amdgpu_drm.h"
#include "amdgpu_internal.h"
-#include "util_hash_table.h"
#include "util_math.h"
static void amdgpu_close_kms_handle(amdgpu_device_handle dev,
@@ -53,41 +48,12 @@ static void amdgpu_close_kms_handle(amdgpu_device_handle dev,
drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &args);
}
-drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo)
-{
- /* Remove the buffer from the hash tables. */
- pthread_mutex_lock(&bo->dev->bo_table_mutex);
- util_hash_table_remove(bo->dev->bo_handles,
- (void*)(uintptr_t)bo->handle);
- if (bo->flink_name) {
- util_hash_table_remove(bo->dev->bo_flink_names,
- (void*)(uintptr_t)bo->flink_name);
- }
- pthread_mutex_unlock(&bo->dev->bo_table_mutex);
-
- /* Release CPU access. */
- if (bo->cpu_map_count > 0) {
- bo->cpu_map_count = 1;
- amdgpu_bo_cpu_unmap(bo);
- }
-
- amdgpu_close_kms_handle(bo->dev, bo->handle);
- pthread_mutex_destroy(&bo->cpu_access_mutex);
- free(bo);
-}
-
-int amdgpu_bo_alloc(amdgpu_device_handle dev,
- struct amdgpu_bo_alloc_request *alloc_buffer,
- amdgpu_bo_handle *buf_handle)
+static int amdgpu_bo_create(amdgpu_device_handle dev,
+ uint64_t size,
+ uint32_t handle,
+ amdgpu_bo_handle *buf_handle)
{
struct amdgpu_bo *bo;
- union drm_amdgpu_gem_create args;
- unsigned heap = alloc_buffer->preferred_heap;
- int r = 0;
-
- /* It's an error if the heap is not specified */
- if (!(heap & (AMDGPU_GEM_DOMAIN_GTT | AMDGPU_GEM_DOMAIN_VRAM)))
- return -EINVAL;
bo = calloc(1, sizeof(struct amdgpu_bo));
if (!bo)
@@ -95,34 +61,54 @@ int amdgpu_bo_alloc(amdgpu_device_handle dev,
atomic_set(&bo->refcount, 1);
bo->dev = dev;
- bo->alloc_size = alloc_buffer->alloc_size;
+ bo->alloc_size = size;
+ bo->handle = handle;
+ pthread_mutex_init(&bo->cpu_access_mutex, NULL);
+
+ *buf_handle = bo;
+ return 0;
+}
+
+drm_public int amdgpu_bo_alloc(amdgpu_device_handle dev,
+ struct amdgpu_bo_alloc_request *alloc_buffer,
+ amdgpu_bo_handle *buf_handle)
+{
+ union drm_amdgpu_gem_create args;
+ int r;
memset(&args, 0, sizeof(args));
args.in.bo_size = alloc_buffer->alloc_size;
args.in.alignment = alloc_buffer->phys_alignment;
/* Set the placement. */
- args.in.domains = heap;
+ args.in.domains = alloc_buffer->preferred_heap;
args.in.domain_flags = alloc_buffer->flags;
/* Allocate the buffer with the preferred heap. */
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_CREATE,
&args, sizeof(args));
+ if (r)
+ goto out;
+
+ r = amdgpu_bo_create(dev, alloc_buffer->alloc_size, args.out.handle,
+ buf_handle);
if (r) {
- free(bo);
- return r;
+ amdgpu_close_kms_handle(dev, args.out.handle);
+ goto out;
}
- bo->handle = args.out.handle;
-
- pthread_mutex_init(&bo->cpu_access_mutex, NULL);
-
- *buf_handle = bo;
- return 0;
+ pthread_mutex_lock(&dev->bo_table_mutex);
+ r = handle_table_insert(&dev->bo_handles, (*buf_handle)->handle,
+ *buf_handle);
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+ if (r)
+ amdgpu_bo_free(*buf_handle);
+out:
+ return r;
}
-int amdgpu_bo_set_metadata(amdgpu_bo_handle bo,
- struct amdgpu_bo_metadata *info)
+drm_public int amdgpu_bo_set_metadata(amdgpu_bo_handle bo,
+ struct amdgpu_bo_metadata *info)
{
struct drm_amdgpu_gem_metadata args = {};
@@ -144,8 +130,8 @@ int amdgpu_bo_set_metadata(amdgpu_bo_handle bo,
&args, sizeof(args));
}
-int amdgpu_bo_query_info(amdgpu_bo_handle bo,
- struct amdgpu_bo_info *info)
+drm_public int amdgpu_bo_query_info(amdgpu_bo_handle bo,
+ struct amdgpu_bo_info *info)
{
struct drm_amdgpu_gem_metadata metadata = {};
struct drm_amdgpu_gem_create_in bo_info = {};
@@ -195,14 +181,6 @@ int amdgpu_bo_query_info(amdgpu_bo_handle bo,
return 0;
}
-static void amdgpu_add_handle_to_table(amdgpu_bo_handle bo)
-{
- pthread_mutex_lock(&bo->dev->bo_table_mutex);
- util_hash_table_set(bo->dev->bo_handles,
- (void*)(uintptr_t)bo->handle, bo);
- pthread_mutex_unlock(&bo->dev->bo_table_mutex);
-}
-
static int amdgpu_bo_export_flink(amdgpu_bo_handle bo)
{
struct drm_gem_flink flink;
@@ -243,17 +221,15 @@ static int amdgpu_bo_export_flink(amdgpu_bo_handle bo)
}
pthread_mutex_lock(&bo->dev->bo_table_mutex);
- util_hash_table_set(bo->dev->bo_flink_names,
- (void*)(uintptr_t)bo->flink_name,
- bo);
+ r = handle_table_insert(&bo->dev->bo_flink_names, bo->flink_name, bo);
pthread_mutex_unlock(&bo->dev->bo_table_mutex);
- return 0;
+ return r;
}
-int amdgpu_bo_export(amdgpu_bo_handle bo,
- enum amdgpu_bo_handle_type type,
- uint32_t *shared_handle)
+drm_public int amdgpu_bo_export(amdgpu_bo_handle bo,
+ enum amdgpu_bo_handle_type type,
+ uint32_t *shared_handle)
{
int r;
@@ -267,26 +243,29 @@ int amdgpu_bo_export(amdgpu_bo_handle bo,
return 0;
case amdgpu_bo_handle_type_kms:
- amdgpu_add_handle_to_table(bo);
+ case amdgpu_bo_handle_type_kms_noimport:
*shared_handle = bo->handle;
return 0;
case amdgpu_bo_handle_type_dma_buf_fd:
- amdgpu_add_handle_to_table(bo);
- return drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC,
- (int*)shared_handle);
+ return drmPrimeHandleToFD(bo->dev->fd, bo->handle,
+ DRM_CLOEXEC | DRM_RDWR,
+ (int*)shared_handle);
}
return -EINVAL;
}
-int amdgpu_bo_import(amdgpu_device_handle dev,
- enum amdgpu_bo_handle_type type,
- uint32_t shared_handle,
+drm_public int amdgpu_bo_import(amdgpu_device_handle dev,
+ enum amdgpu_bo_handle_type type,
+ uint32_t shared_handle,
struct amdgpu_bo_import_result *output)
{
struct drm_gem_open open_arg = {};
+ struct drm_gem_close close_arg = {};
struct amdgpu_bo *bo = NULL;
- int r;
+ uint32_t handle = 0, flink_name = 0;
+ uint64_t alloc_size = 0;
+ int r = 0;
int dma_fd;
uint64_t dma_buf_size = 0;
@@ -296,21 +275,18 @@ int amdgpu_bo_import(amdgpu_device_handle dev,
/* Convert a DMA buf handle to a KMS handle now. */
if (type == amdgpu_bo_handle_type_dma_buf_fd) {
- uint32_t handle;
off_t size;
/* Get a KMS handle. */
r = drmPrimeFDToHandle(dev->fd, shared_handle, &handle);
- if (r) {
- return r;
- }
+ if (r)
+ goto unlock;
/* Query the buffer size. */
size = lseek(shared_handle, 0, SEEK_END);
if (size == (off_t)-1) {
- pthread_mutex_unlock(&dev->bo_table_mutex);
- amdgpu_close_kms_handle(dev, handle);
- return -errno;
+ r = -errno;
+ goto free_bo_handle;
}
lseek(shared_handle, 0, SEEK_SET);
@@ -321,110 +297,148 @@ int amdgpu_bo_import(amdgpu_device_handle dev,
/* If we have already created a buffer with this handle, find it. */
switch (type) {
case amdgpu_bo_handle_type_gem_flink_name:
- bo = util_hash_table_get(dev->bo_flink_names,
- (void*)(uintptr_t)shared_handle);
+ bo = handle_table_lookup(&dev->bo_flink_names, shared_handle);
break;
case amdgpu_bo_handle_type_dma_buf_fd:
- bo = util_hash_table_get(dev->bo_handles,
- (void*)(uintptr_t)shared_handle);
+ bo = handle_table_lookup(&dev->bo_handles, shared_handle);
break;
case amdgpu_bo_handle_type_kms:
+ case amdgpu_bo_handle_type_kms_noimport:
/* Importing a KMS handle in not allowed. */
- pthread_mutex_unlock(&dev->bo_table_mutex);
- return -EPERM;
+ r = -EPERM;
+ goto unlock;
default:
- pthread_mutex_unlock(&dev->bo_table_mutex);
- return -EINVAL;
+ r = -EINVAL;
+ goto unlock;
}
if (bo) {
- pthread_mutex_unlock(&dev->bo_table_mutex);
-
/* The buffer already exists, just bump the refcount. */
atomic_inc(&bo->refcount);
+ pthread_mutex_unlock(&dev->bo_table_mutex);
output->buf_handle = bo;
output->alloc_size = bo->alloc_size;
return 0;
}
- bo = calloc(1, sizeof(struct amdgpu_bo));
- if (!bo) {
- pthread_mutex_unlock(&dev->bo_table_mutex);
- if (type == amdgpu_bo_handle_type_dma_buf_fd) {
- amdgpu_close_kms_handle(dev, shared_handle);
- }
- return -ENOMEM;
- }
-
/* Open the handle. */
switch (type) {
case amdgpu_bo_handle_type_gem_flink_name:
open_arg.name = shared_handle;
r = drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_OPEN, &open_arg);
- if (r) {
- free(bo);
- pthread_mutex_unlock(&dev->bo_table_mutex);
- return r;
- }
+ if (r)
+ goto unlock;
- bo->handle = open_arg.handle;
+ flink_name = shared_handle;
+ handle = open_arg.handle;
+ alloc_size = open_arg.size;
if (dev->flink_fd != dev->fd) {
- r = drmPrimeHandleToFD(dev->flink_fd, bo->handle, DRM_CLOEXEC, &dma_fd);
- if (r) {
- free(bo);
- pthread_mutex_unlock(&dev->bo_table_mutex);
- return r;
- }
- r = drmPrimeFDToHandle(dev->fd, dma_fd, &bo->handle );
-
+ r = drmPrimeHandleToFD(dev->flink_fd, handle,
+ DRM_CLOEXEC, &dma_fd);
+ if (r)
+ goto free_bo_handle;
+ r = drmPrimeFDToHandle(dev->fd, dma_fd, &handle);
close(dma_fd);
-
- if (r) {
- free(bo);
- pthread_mutex_unlock(&dev->bo_table_mutex);
- return r;
- }
+ if (r)
+ goto free_bo_handle;
+ close_arg.handle = open_arg.handle;
+ r = drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_CLOSE,
+ &close_arg);
+ if (r)
+ goto free_bo_handle;
}
- bo->flink_name = shared_handle;
- bo->alloc_size = open_arg.size;
- util_hash_table_set(dev->bo_flink_names,
- (void*)(uintptr_t)bo->flink_name, bo);
break;
case amdgpu_bo_handle_type_dma_buf_fd:
- bo->handle = shared_handle;
- bo->alloc_size = dma_buf_size;
+ handle = shared_handle;
+ alloc_size = dma_buf_size;
break;
case amdgpu_bo_handle_type_kms:
+ case amdgpu_bo_handle_type_kms_noimport:
assert(0); /* unreachable */
}
/* Initialize it. */
- atomic_set(&bo->refcount, 1);
- bo->dev = dev;
- pthread_mutex_init(&bo->cpu_access_mutex, NULL);
+ r = amdgpu_bo_create(dev, alloc_size, handle, &bo);
+ if (r)
+ goto free_bo_handle;
- util_hash_table_set(dev->bo_handles, (void*)(uintptr_t)bo->handle, bo);
- pthread_mutex_unlock(&dev->bo_table_mutex);
+ r = handle_table_insert(&dev->bo_handles, bo->handle, bo);
+ if (r)
+ goto free_bo_handle;
+ if (flink_name) {
+ bo->flink_name = flink_name;
+ r = handle_table_insert(&dev->bo_flink_names, flink_name,
+ bo);
+ if (r)
+ goto remove_handle;
+
+ }
output->buf_handle = bo;
output->alloc_size = bo->alloc_size;
+ pthread_mutex_unlock(&dev->bo_table_mutex);
return 0;
+
+remove_handle:
+ handle_table_remove(&dev->bo_handles, bo->handle);
+free_bo_handle:
+ if (flink_name && !close_arg.handle && open_arg.handle) {
+ close_arg.handle = open_arg.handle;
+ drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_CLOSE, &close_arg);
+ }
+ if (bo)
+ amdgpu_bo_free(bo);
+ else
+ amdgpu_close_kms_handle(dev, handle);
+unlock:
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+ return r;
}
-int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
+drm_public int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
{
- /* Just drop the reference. */
- amdgpu_bo_reference(&buf_handle, NULL);
+ struct amdgpu_device *dev;
+ struct amdgpu_bo *bo = buf_handle;
+
+ assert(bo != NULL);
+ dev = bo->dev;
+ pthread_mutex_lock(&dev->bo_table_mutex);
+
+ if (update_references(&bo->refcount, NULL)) {
+ /* Remove the buffer from the hash tables. */
+ handle_table_remove(&dev->bo_handles, bo->handle);
+
+ if (bo->flink_name)
+ handle_table_remove(&dev->bo_flink_names,
+ bo->flink_name);
+
+ /* Release CPU access. */
+ if (bo->cpu_map_count > 0) {
+ bo->cpu_map_count = 1;
+ amdgpu_bo_cpu_unmap(bo);
+ }
+
+ amdgpu_close_kms_handle(dev, bo->handle);
+ pthread_mutex_destroy(&bo->cpu_access_mutex);
+ free(bo);
+ }
+
+ pthread_mutex_unlock(&dev->bo_table_mutex);
return 0;
}
-int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu)
+drm_public void amdgpu_bo_inc_ref(amdgpu_bo_handle bo)
+{
+ atomic_inc(&bo->refcount);
+}
+
+drm_public int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu)
{
union drm_amdgpu_gem_mmap args;
void *ptr;
@@ -472,7 +486,7 @@ int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu)
return 0;
}
-int amdgpu_bo_cpu_unmap(amdgpu_bo_handle bo)
+drm_public int amdgpu_bo_cpu_unmap(amdgpu_bo_handle bo)
{
int r;
@@ -498,7 +512,7 @@ int amdgpu_bo_cpu_unmap(amdgpu_bo_handle bo)
return r;
}
-int amdgpu_query_buffer_size_alignment(amdgpu_device_handle dev,
+drm_public int amdgpu_query_buffer_size_alignment(amdgpu_device_handle dev,
struct amdgpu_buffer_size_alignments *info)
{
info->size_local = dev->dev_info.pte_fragment_size;
@@ -506,8 +520,8 @@ int amdgpu_query_buffer_size_alignment(amdgpu_device_handle dev,
return 0;
}
-int amdgpu_bo_wait_for_idle(amdgpu_bo_handle bo,
- uint64_t timeout_ns,
+drm_public int amdgpu_bo_wait_for_idle(amdgpu_bo_handle bo,
+ uint64_t timeout_ns,
bool *busy)
{
union drm_amdgpu_gem_wait_idle args;
@@ -529,13 +543,54 @@ int amdgpu_bo_wait_for_idle(amdgpu_bo_handle bo,
}
}
-int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
- void *cpu,
- uint64_t size,
- amdgpu_bo_handle *buf_handle)
+drm_public int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle dev,
+ void *cpu,
+ uint64_t size,
+ amdgpu_bo_handle *buf_handle,
+ uint64_t *offset_in_bo)
{
- int r;
struct amdgpu_bo *bo;
+ uint32_t i;
+ int r = 0;
+
+ if (cpu == NULL || size == 0)
+ return -EINVAL;
+
+ /*
+ * Workaround for a buggy application which tries to import previously
+ * exposed CPU pointers. If we find a real world use case we should
+ * improve that by asking the kernel for the right handle.
+ */
+ pthread_mutex_lock(&dev->bo_table_mutex);
+ for (i = 0; i < dev->bo_handles.max_key; i++) {
+ bo = handle_table_lookup(&dev->bo_handles, i);
+ if (!bo || !bo->cpu_ptr || size > bo->alloc_size)
+ continue;
+ if (cpu >= bo->cpu_ptr &&
+ cpu < (void*)((uintptr_t)bo->cpu_ptr + bo->alloc_size))
+ break;
+ }
+
+ if (i < dev->bo_handles.max_key) {
+ atomic_inc(&bo->refcount);
+ *buf_handle = bo;
+ *offset_in_bo = (uintptr_t)cpu - (uintptr_t)bo->cpu_ptr;
+ } else {
+ *buf_handle = NULL;
+ *offset_in_bo = 0;
+ r = -ENXIO;
+ }
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+
+ return r;
+}
+
+drm_public int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
+ void *cpu,
+ uint64_t size,
+ amdgpu_bo_handle *buf_handle)
+{
+ int r;
struct drm_amdgpu_gem_userptr args;
args.addr = (uintptr_t)cpu;
@@ -545,27 +600,63 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_USERPTR,
&args, sizeof(args));
if (r)
- return r;
+ goto out;
- bo = calloc(1, sizeof(struct amdgpu_bo));
- if (!bo)
- return -ENOMEM;
+ r = amdgpu_bo_create(dev, size, args.handle, buf_handle);
+ if (r) {
+ amdgpu_close_kms_handle(dev, args.handle);
+ goto out;
+ }
- atomic_set(&bo->refcount, 1);
- bo->dev = dev;
- bo->alloc_size = size;
- bo->handle = args.handle;
+ pthread_mutex_lock(&dev->bo_table_mutex);
+ r = handle_table_insert(&dev->bo_handles, (*buf_handle)->handle,
+ *buf_handle);
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+ if (r)
+ amdgpu_bo_free(*buf_handle);
+out:
+ return r;
+}
- *buf_handle = bo;
+drm_public int amdgpu_bo_list_create_raw(amdgpu_device_handle dev,
+ uint32_t number_of_buffers,
+ struct drm_amdgpu_bo_list_entry *buffers,
+ uint32_t *result)
+{
+ union drm_amdgpu_bo_list args;
+ int r;
+
+ memset(&args, 0, sizeof(args));
+ args.in.operation = AMDGPU_BO_LIST_OP_CREATE;
+ args.in.bo_number = number_of_buffers;
+ args.in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
+ args.in.bo_info_ptr = (uint64_t)(uintptr_t)buffers;
+ r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_BO_LIST,
+ &args, sizeof(args));
+ if (!r)
+ *result = args.out.list_handle;
return r;
}
-int amdgpu_bo_list_create(amdgpu_device_handle dev,
- uint32_t number_of_resources,
- amdgpu_bo_handle *resources,
- uint8_t *resource_prios,
- amdgpu_bo_list_handle *result)
+drm_public int amdgpu_bo_list_destroy_raw(amdgpu_device_handle dev,
+ uint32_t bo_list)
+{
+ union drm_amdgpu_bo_list args;
+
+ memset(&args, 0, sizeof(args));
+ args.in.operation = AMDGPU_BO_LIST_OP_DESTROY;
+ args.in.list_handle = bo_list;
+
+ return drmCommandWriteRead(dev->fd, DRM_AMDGPU_BO_LIST,
+ &args, sizeof(args));
+}
+
+drm_public int amdgpu_bo_list_create(amdgpu_device_handle dev,
+ uint32_t number_of_resources,
+ amdgpu_bo_handle *resources,
+ uint8_t *resource_prios,
+ amdgpu_bo_list_handle *result)
{
struct drm_amdgpu_bo_list_entry *list;
union drm_amdgpu_bo_list args;
@@ -616,7 +707,7 @@ int amdgpu_bo_list_create(amdgpu_device_handle dev,
return 0;
}
-int amdgpu_bo_list_destroy(amdgpu_bo_list_handle list)
+drm_public int amdgpu_bo_list_destroy(amdgpu_bo_list_handle list)
{
union drm_amdgpu_bo_list args;
int r;
@@ -634,10 +725,10 @@ int amdgpu_bo_list_destroy(amdgpu_bo_list_handle list)
return r;
}
-int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
- uint32_t number_of_resources,
- amdgpu_bo_handle *resources,
- uint8_t *resource_prios)
+drm_public int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
+ uint32_t number_of_resources,
+ amdgpu_bo_handle *resources,
+ uint8_t *resource_prios)
{
struct drm_amdgpu_bo_list_entry *list;
union drm_amdgpu_bo_list args;
@@ -652,7 +743,7 @@ int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
return -EINVAL;
list = malloc(number_of_resources * sizeof(struct drm_amdgpu_bo_list_entry));
- if (list == NULL)
+ if (!list)
return -ENOMEM;
args.in.operation = AMDGPU_BO_LIST_OP_UPDATE;
@@ -675,29 +766,45 @@ int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
return r;
}
-int amdgpu_bo_va_op(amdgpu_bo_handle bo,
- uint64_t offset,
- uint64_t size,
- uint64_t addr,
- uint64_t flags,
- uint32_t ops)
+drm_public int amdgpu_bo_va_op(amdgpu_bo_handle bo,
+ uint64_t offset,
+ uint64_t size,
+ uint64_t addr,
+ uint64_t flags,
+ uint32_t ops)
{
amdgpu_device_handle dev = bo->dev;
+
+ size = ALIGN(size, getpagesize());
+
+ return amdgpu_bo_va_op_raw(dev, bo, offset, size, addr,
+ AMDGPU_VM_PAGE_READABLE |
+ AMDGPU_VM_PAGE_WRITEABLE |
+ AMDGPU_VM_PAGE_EXECUTABLE, ops);
+}
+
+drm_public int amdgpu_bo_va_op_raw(amdgpu_device_handle dev,
+ amdgpu_bo_handle bo,
+ uint64_t offset,
+ uint64_t size,
+ uint64_t addr,
+ uint64_t flags,
+ uint32_t ops)
+{
struct drm_amdgpu_gem_va va;
int r;
- if (ops != AMDGPU_VA_OP_MAP && ops != AMDGPU_VA_OP_UNMAP)
+ if (ops != AMDGPU_VA_OP_MAP && ops != AMDGPU_VA_OP_UNMAP &&
+ ops != AMDGPU_VA_OP_REPLACE && ops != AMDGPU_VA_OP_CLEAR)
return -EINVAL;
memset(&va, 0, sizeof(va));
- va.handle = bo->handle;
+ va.handle = bo ? bo->handle : 0;
va.operation = ops;
- va.flags = AMDGPU_VM_PAGE_READABLE |
- AMDGPU_VM_PAGE_WRITEABLE |
- AMDGPU_VM_PAGE_EXECUTABLE;
+ va.flags = flags;
va.va_address = addr;
va.offset_in_bo = offset;
- va.map_size = ALIGN(size, getpagesize());
+ va.map_size = size;
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_VA, &va, sizeof(va));
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index fb5b3a8c..ba158f2a 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -21,10 +21,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -46,26 +42,26 @@ static int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem);
/**
* Create command submission context
*
- * \param dev - \c [in] amdgpu device handle
- * \param context - \c [out] amdgpu context handle
+ * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
+ * \param priority - \c [in] Context creation flags. See AMDGPU_CTX_PRIORITY_*
+ * \param context - \c [out] GPU Context handle
*
* \return 0 on success otherwise POSIX Error code
*/
-int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
- amdgpu_context_handle *context)
+drm_public int amdgpu_cs_ctx_create2(amdgpu_device_handle dev,
+ uint32_t priority,
+ amdgpu_context_handle *context)
{
struct amdgpu_context *gpu_context;
union drm_amdgpu_ctx args;
int i, j, k;
int r;
- if (NULL == dev)
- return -EINVAL;
- if (NULL == context)
+ if (!dev || !context)
return -EINVAL;
gpu_context = calloc(1, sizeof(struct amdgpu_context));
- if (NULL == gpu_context)
+ if (!gpu_context)
return -ENOMEM;
gpu_context->dev = dev;
@@ -77,6 +73,8 @@ int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
/* Create the context */
memset(&args, 0, sizeof(args));
args.in.op = AMDGPU_CTX_OP_ALLOC_CTX;
+ args.in.priority = priority;
+
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CTX, &args, sizeof(args));
if (r)
goto error;
@@ -96,6 +94,12 @@ error:
return r;
}
+drm_public int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
+ amdgpu_context_handle *context)
+{
+ return amdgpu_cs_ctx_create2(dev, AMDGPU_CTX_PRIORITY_NORMAL, context);
+}
+
/**
* Release command submission context
*
@@ -104,13 +108,13 @@ error:
*
* \return 0 on success otherwise POSIX Error code
*/
-int amdgpu_cs_ctx_free(amdgpu_context_handle context)
+drm_public int amdgpu_cs_ctx_free(amdgpu_context_handle context)
{
union drm_amdgpu_ctx args;
int i, j, k;
int r;
- if (NULL == context)
+ if (!context)
return -EINVAL;
pthread_mutex_destroy(&context->sequence_mutex);
@@ -138,8 +142,8 @@ int amdgpu_cs_ctx_free(amdgpu_context_handle context)
return r;
}
-int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
- uint32_t *state, uint32_t *hangs)
+drm_public int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
+ uint32_t *state, uint32_t *hangs)
{
union drm_amdgpu_ctx args;
int r;
@@ -188,8 +192,6 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
return -EINVAL;
if (ibs_request->ring >= AMDGPU_CS_MAX_RINGS)
return -EINVAL;
- if (ibs_request->number_of_ibs > AMDGPU_CS_MAX_IBS_PER_SUBMIT)
- return -EINVAL;
if (ibs_request->number_of_ibs == 0) {
ibs_request->seq_no = AMDGPU_NULL_SUBMIT_SEQ;
return 0;
@@ -322,17 +324,15 @@ error_unlock:
return r;
}
-int amdgpu_cs_submit(amdgpu_context_handle context,
- uint64_t flags,
- struct amdgpu_cs_request *ibs_request,
- uint32_t number_of_requests)
+drm_public int amdgpu_cs_submit(amdgpu_context_handle context,
+ uint64_t flags,
+ struct amdgpu_cs_request *ibs_request,
+ uint32_t number_of_requests)
{
uint32_t i;
int r;
- if (NULL == context)
- return -EINVAL;
- if (NULL == ibs_request)
+ if (!context || !ibs_request)
return -EINVAL;
r = 0;
@@ -408,19 +408,15 @@ static int amdgpu_ioctl_wait_cs(amdgpu_context_handle context,
return 0;
}
-int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence,
- uint64_t timeout_ns,
- uint64_t flags,
- uint32_t *expired)
+drm_public int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence,
+ uint64_t timeout_ns,
+ uint64_t flags,
+ uint32_t *expired)
{
bool busy = true;
int r;
- if (NULL == fence)
- return -EINVAL;
- if (NULL == expired)
- return -EINVAL;
- if (NULL == fence->context)
+ if (!fence || !expired || !fence->context)
return -EINVAL;
if (fence->ip_type >= AMDGPU_HW_IP_NUM)
return -EINVAL;
@@ -443,15 +439,83 @@ int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence,
return r;
}
-int amdgpu_cs_create_semaphore(amdgpu_semaphore_handle *sem)
+static int amdgpu_ioctl_wait_fences(struct amdgpu_cs_fence *fences,
+ uint32_t fence_count,
+ bool wait_all,
+ uint64_t timeout_ns,
+ uint32_t *status,
+ uint32_t *first)
+{
+ struct drm_amdgpu_fence *drm_fences;
+ amdgpu_device_handle dev = fences[0].context->dev;
+ union drm_amdgpu_wait_fences args;
+ int r;
+ uint32_t i;
+
+ drm_fences = alloca(sizeof(struct drm_amdgpu_fence) * fence_count);
+ for (i = 0; i < fence_count; i++) {
+ drm_fences[i].ctx_id = fences[i].context->id;
+ drm_fences[i].ip_type = fences[i].ip_type;
+ drm_fences[i].ip_instance = fences[i].ip_instance;
+ drm_fences[i].ring = fences[i].ring;
+ drm_fences[i].seq_no = fences[i].fence;
+ }
+
+ memset(&args, 0, sizeof(args));
+ args.in.fences = (uint64_t)(uintptr_t)drm_fences;
+ args.in.fence_count = fence_count;
+ args.in.wait_all = wait_all;
+ args.in.timeout_ns = amdgpu_cs_calculate_timeout(timeout_ns);
+
+ r = drmIoctl(dev->fd, DRM_IOCTL_AMDGPU_WAIT_FENCES, &args);
+ if (r)
+ return -errno;
+
+ *status = args.out.status;
+
+ if (first)
+ *first = args.out.first_signaled;
+
+ return 0;
+}
+
+drm_public int amdgpu_cs_wait_fences(struct amdgpu_cs_fence *fences,
+ uint32_t fence_count,
+ bool wait_all,
+ uint64_t timeout_ns,
+ uint32_t *status,
+ uint32_t *first)
+{
+ uint32_t i;
+
+ /* Sanity check */
+ if (!fences || !status || !fence_count)
+ return -EINVAL;
+
+ for (i = 0; i < fence_count; i++) {
+ if (NULL == fences[i].context)
+ return -EINVAL;
+ if (fences[i].ip_type >= AMDGPU_HW_IP_NUM)
+ return -EINVAL;
+ if (fences[i].ring >= AMDGPU_CS_MAX_RINGS)
+ return -EINVAL;
+ }
+
+ *status = 0;
+
+ return amdgpu_ioctl_wait_fences(fences, fence_count, wait_all,
+ timeout_ns, status, first);
+}
+
+drm_public int amdgpu_cs_create_semaphore(amdgpu_semaphore_handle *sem)
{
struct amdgpu_semaphore *gpu_semaphore;
- if (NULL == sem)
+ if (!sem)
return -EINVAL;
gpu_semaphore = calloc(1, sizeof(struct amdgpu_semaphore));
- if (NULL == gpu_semaphore)
+ if (!gpu_semaphore)
return -ENOMEM;
atomic_set(&gpu_semaphore->refcount, 1);
@@ -460,20 +524,18 @@ int amdgpu_cs_create_semaphore(amdgpu_semaphore_handle *sem)
return 0;
}
-int amdgpu_cs_signal_semaphore(amdgpu_context_handle ctx,
- uint32_t ip_type,
+drm_public int amdgpu_cs_signal_semaphore(amdgpu_context_handle ctx,
+ uint32_t ip_type,
uint32_t ip_instance,
uint32_t ring,
amdgpu_semaphore_handle sem)
{
- if (NULL == ctx)
+ if (!ctx || !sem)
return -EINVAL;
if (ip_type >= AMDGPU_HW_IP_NUM)
return -EINVAL;
if (ring >= AMDGPU_CS_MAX_RINGS)
return -EINVAL;
- if (NULL == sem)
- return -EINVAL;
/* sem has been signaled */
if (sem->signal_fence.context)
return -EINVAL;
@@ -488,22 +550,20 @@ int amdgpu_cs_signal_semaphore(amdgpu_context_handle ctx,
return 0;
}
-int amdgpu_cs_wait_semaphore(amdgpu_context_handle ctx,
- uint32_t ip_type,
+drm_public int amdgpu_cs_wait_semaphore(amdgpu_context_handle ctx,
+ uint32_t ip_type,
uint32_t ip_instance,
uint32_t ring,
amdgpu_semaphore_handle sem)
{
- if (NULL == ctx)
+ if (!ctx || !sem)
return -EINVAL;
if (ip_type >= AMDGPU_HW_IP_NUM)
return -EINVAL;
if (ring >= AMDGPU_CS_MAX_RINGS)
return -EINVAL;
- if (NULL == sem)
- return -EINVAL;
/* must signal first */
- if (NULL == sem->signal_fence.context)
+ if (!sem->signal_fence.context)
return -EINVAL;
pthread_mutex_lock(&ctx->sequence_mutex);
@@ -514,12 +574,10 @@ int amdgpu_cs_wait_semaphore(amdgpu_context_handle ctx,
static int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem)
{
- if (NULL == sem)
- return -EINVAL;
- if (NULL == sem->signal_fence.context)
+ if (!sem || !sem->signal_fence.context)
return -EINVAL;
- sem->signal_fence.context = NULL;;
+ sem->signal_fence.context = NULL;
sem->signal_fence.ip_type = 0;
sem->signal_fence.ip_instance = 0;
sem->signal_fence.ring = 0;
@@ -530,7 +588,7 @@ static int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem)
static int amdgpu_cs_unreference_sem(amdgpu_semaphore_handle sem)
{
- if (NULL == sem)
+ if (!sem)
return -EINVAL;
if (update_references(&sem->refcount, NULL))
@@ -538,7 +596,204 @@ static int amdgpu_cs_unreference_sem(amdgpu_semaphore_handle sem)
return 0;
}
-int amdgpu_cs_destroy_semaphore(amdgpu_semaphore_handle sem)
+drm_public int amdgpu_cs_destroy_semaphore(amdgpu_semaphore_handle sem)
{
return amdgpu_cs_unreference_sem(sem);
}
+
+drm_public int amdgpu_cs_create_syncobj2(amdgpu_device_handle dev,
+ uint32_t flags,
+ uint32_t *handle)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjCreate(dev->fd, flags, handle);
+}
+
+drm_public int amdgpu_cs_create_syncobj(amdgpu_device_handle dev,
+ uint32_t *handle)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjCreate(dev->fd, 0, handle);
+}
+
+drm_public int amdgpu_cs_destroy_syncobj(amdgpu_device_handle dev,
+ uint32_t handle)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjDestroy(dev->fd, handle);
+}
+
+drm_public int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint32_t syncobj_count)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjReset(dev->fd, syncobjs, syncobj_count);
+}
+
+drm_public int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint32_t syncobj_count)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
+}
+
+drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
+ uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjWait(dev->fd, handles, num_handles, timeout_nsec,
+ flags, first_signaled);
+}
+
+drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
+ uint32_t handle,
+ int *shared_fd)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjHandleToFD(dev->fd, handle, shared_fd);
+}
+
+drm_public int amdgpu_cs_import_syncobj(amdgpu_device_handle dev,
+ int shared_fd,
+ uint32_t *handle)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjFDToHandle(dev->fd, shared_fd, handle);
+}
+
+drm_public int amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int *sync_file_fd)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjExportSyncFile(dev->fd, syncobj, sync_file_fd);
+}
+
+drm_public int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
+ uint32_t syncobj,
+ int sync_file_fd)
+{
+ if (NULL == dev)
+ return -EINVAL;
+
+ return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
+}
+
+drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
+ amdgpu_context_handle context,
+ amdgpu_bo_list_handle bo_list_handle,
+ int num_chunks,
+ struct drm_amdgpu_cs_chunk *chunks,
+ uint64_t *seq_no)
+{
+ union drm_amdgpu_cs cs;
+ uint64_t *chunk_array;
+ int i, r;
+ if (num_chunks == 0)
+ return -EINVAL;
+
+ memset(&cs, 0, sizeof(cs));
+ chunk_array = alloca(sizeof(uint64_t) * num_chunks);
+ for (i = 0; i < num_chunks; i++)
+ chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
+ cs.in.chunks = (uint64_t)(uintptr_t)chunk_array;
+ cs.in.ctx_id = context->id;
+ cs.in.bo_list_handle = bo_list_handle ? bo_list_handle->handle : 0;
+ cs.in.num_chunks = num_chunks;
+ r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CS,
+ &cs, sizeof(cs));
+ if (r)
+ return r;
+
+ if (seq_no)
+ *seq_no = cs.out.handle;
+ return 0;
+}
+
+drm_public int amdgpu_cs_submit_raw2(amdgpu_device_handle dev,
+ amdgpu_context_handle context,
+ uint32_t bo_list_handle,
+ int num_chunks,
+ struct drm_amdgpu_cs_chunk *chunks,
+ uint64_t *seq_no)
+{
+ union drm_amdgpu_cs cs;
+ uint64_t *chunk_array;
+ int i, r;
+
+ memset(&cs, 0, sizeof(cs));
+ chunk_array = alloca(sizeof(uint64_t) * num_chunks);
+ for (i = 0; i < num_chunks; i++)
+ chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
+ cs.in.chunks = (uint64_t)(uintptr_t)chunk_array;
+ cs.in.ctx_id = context->id;
+ cs.in.bo_list_handle = bo_list_handle;
+ cs.in.num_chunks = num_chunks;
+ r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CS,
+ &cs, sizeof(cs));
+ if (!r && seq_no)
+ *seq_no = cs.out.handle;
+ return r;
+}
+
+drm_public void amdgpu_cs_chunk_fence_info_to_data(struct amdgpu_cs_fence_info *fence_info,
+ struct drm_amdgpu_cs_chunk_data *data)
+{
+ data->fence_data.handle = fence_info->handle->handle;
+ data->fence_data.offset = fence_info->offset * sizeof(uint64_t);
+}
+
+drm_public void amdgpu_cs_chunk_fence_to_dep(struct amdgpu_cs_fence *fence,
+ struct drm_amdgpu_cs_chunk_dep *dep)
+{
+ dep->ip_type = fence->ip_type;
+ dep->ip_instance = fence->ip_instance;
+ dep->ring = fence->ring;
+ dep->ctx_id = fence->context->id;
+ dep->handle = fence->fence;
+}
+
+drm_public int amdgpu_cs_fence_to_handle(amdgpu_device_handle dev,
+ struct amdgpu_cs_fence *fence,
+ uint32_t what,
+ uint32_t *out_handle)
+{
+ union drm_amdgpu_fence_to_handle fth;
+ int r;
+
+ memset(&fth, 0, sizeof(fth));
+ fth.in.fence.ctx_id = fence->context->id;
+ fth.in.fence.ip_type = fence->ip_type;
+ fth.in.fence.ip_instance = fence->ip_instance;
+ fth.in.fence.ring = fence->ring;
+ fth.in.fence.seq_no = fence->fence;
+ fth.in.what = what;
+
+ r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_FENCE_TO_HANDLE,
+ &fth, sizeof(fth));
+ if (r == 0)
+ *out_handle = fth.out.handle;
+ return r;
+}
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index f4ede031..362494b1 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -28,62 +28,26 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <fcntl.h>
#include "xf86drm.h"
#include "amdgpu_drm.h"
#include "amdgpu_internal.h"
-#include "util_hash_table.h"
#include "util_math.h"
-#include "amdgpu_asic_id.h"
#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
-#define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
static pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER;
-static struct util_hash_table *fd_tab;
-
-static unsigned handle_hash(void *key)
-{
- return PTR_TO_UINT(key);
-}
-
-static int handle_compare(void *key1, void *key2)
-{
- return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
-}
-
-static unsigned fd_hash(void *key)
-{
- int fd = PTR_TO_UINT(key);
- char *name = drmGetPrimaryDeviceNameFromFd(fd);
- unsigned result = 0;
- char *c;
-
- if (name == NULL)
- return 0;
-
- for (c = name; *c; ++c)
- result += *c;
-
- free(name);
-
- return result;
-}
+static amdgpu_device_handle fd_list;
-static int fd_compare(void *key1, void *key2)
+static int fd_compare(int fd1, int fd2)
{
- int fd1 = PTR_TO_UINT(key1);
- int fd2 = PTR_TO_UINT(key2);
char *name1 = drmGetPrimaryDeviceNameFromFd(fd1);
char *name2 = drmGetPrimaryDeviceNameFromFd(fd2);
int result;
@@ -131,17 +95,26 @@ static int amdgpu_get_auth(int fd, int *auth)
static void amdgpu_device_free_internal(amdgpu_device_handle dev)
{
- amdgpu_vamgr_deinit(dev->vamgr);
- free(dev->vamgr);
- amdgpu_vamgr_deinit(dev->vamgr_32);
- free(dev->vamgr_32);
- util_hash_table_destroy(dev->bo_flink_names);
- util_hash_table_destroy(dev->bo_handles);
- pthread_mutex_destroy(&dev->bo_table_mutex);
- util_hash_table_remove(fd_tab, UINT_TO_PTR(dev->fd));
+ amdgpu_device_handle *node = &fd_list;
+
+ pthread_mutex_lock(&fd_mutex);
+ while (*node != dev && (*node)->next)
+ node = &(*node)->next;
+ *node = (*node)->next;
+ pthread_mutex_unlock(&fd_mutex);
+
close(dev->fd);
if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
close(dev->flink_fd);
+
+ amdgpu_vamgr_deinit(&dev->vamgr_32);
+ amdgpu_vamgr_deinit(&dev->vamgr);
+ amdgpu_vamgr_deinit(&dev->vamgr_high_32);
+ amdgpu_vamgr_deinit(&dev->vamgr_high);
+ handle_table_fini(&dev->bo_handles);
+ handle_table_fini(&dev->bo_flink_names);
+ pthread_mutex_destroy(&dev->bo_table_mutex);
+ free(dev->marketing_name);
free(dev);
}
@@ -160,17 +133,17 @@ static void amdgpu_device_free_internal(amdgpu_device_handle dev)
* // incremented. dst is freed if its reference counter is 0.
*/
static void amdgpu_device_reference(struct amdgpu_device **dst,
- struct amdgpu_device *src)
+ struct amdgpu_device *src)
{
if (update_references(&(*dst)->refcount, &src->refcount))
amdgpu_device_free_internal(*dst);
*dst = src;
}
-int amdgpu_device_initialize(int fd,
- uint32_t *major_version,
- uint32_t *minor_version,
- amdgpu_device_handle *device_handle)
+drm_public int amdgpu_device_initialize(int fd,
+ uint32_t *major_version,
+ uint32_t *minor_version,
+ amdgpu_device_handle *device_handle)
{
struct amdgpu_device *dev;
drmVersionPtr version;
@@ -183,22 +156,28 @@ int amdgpu_device_initialize(int fd,
*device_handle = NULL;
pthread_mutex_lock(&fd_mutex);
- if (!fd_tab)
- fd_tab = util_hash_table_create(fd_hash, fd_compare);
r = amdgpu_get_auth(fd, &flag_auth);
if (r) {
+ fprintf(stderr, "%s: amdgpu_get_auth (1) failed (%i)\n",
+ __func__, r);
pthread_mutex_unlock(&fd_mutex);
return r;
}
- dev = util_hash_table_get(fd_tab, UINT_TO_PTR(fd));
+
+ for (dev = fd_list; dev; dev = dev->next)
+ if (fd_compare(dev->fd, fd) == 0)
+ break;
+
if (dev) {
r = amdgpu_get_auth(dev->fd, &flag_authexist);
if (r) {
+ fprintf(stderr, "%s: amdgpu_get_auth (2) failed (%i)\n",
+ __func__, r);
pthread_mutex_unlock(&fd_mutex);
return r;
}
if ((flag_auth) && (!flag_authexist)) {
- dev->flink_fd = dup(fd);
+ dev->flink_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
}
*major_version = dev->major_version;
*minor_version = dev->minor_version;
@@ -209,6 +188,7 @@ int amdgpu_device_initialize(int fd,
dev = calloc(1, sizeof(struct amdgpu_device));
if (!dev) {
+ fprintf(stderr, "%s: calloc failed\n", __func__);
pthread_mutex_unlock(&fd_mutex);
return -ENOMEM;
}
@@ -231,66 +211,66 @@ int amdgpu_device_initialize(int fd,
goto cleanup;
}
- dev->fd = dup(fd);
+ dev->fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
dev->flink_fd = dev->fd;
dev->major_version = version->version_major;
dev->minor_version = version->version_minor;
drmFreeVersion(version);
- dev->bo_flink_names = util_hash_table_create(handle_hash,
- handle_compare);
- dev->bo_handles = util_hash_table_create(handle_hash, handle_compare);
pthread_mutex_init(&dev->bo_table_mutex, NULL);
/* Check if acceleration is working. */
r = amdgpu_query_info(dev, AMDGPU_INFO_ACCEL_WORKING, 4, &accel_working);
- if (r)
+ if (r) {
+ fprintf(stderr, "%s: amdgpu_query_info(ACCEL_WORKING) failed (%i)\n",
+ __func__, r);
goto cleanup;
+ }
if (!accel_working) {
+ fprintf(stderr, "%s: AMDGPU_INFO_ACCEL_WORKING = 0\n", __func__);
r = -EBADF;
goto cleanup;
}
r = amdgpu_query_gpu_info_init(dev);
- if (r)
+ if (r) {
+ fprintf(stderr, "%s: amdgpu_query_gpu_info_init failed\n", __func__);
goto cleanup;
+ }
- dev->vamgr = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
- if (dev->vamgr == NULL)
- goto cleanup;
+ start = dev->dev_info.virtual_address_offset;
+ max = MIN2(dev->dev_info.virtual_address_max, 0x100000000ULL);
+ amdgpu_vamgr_init(&dev->vamgr_32, start, max,
+ dev->dev_info.virtual_address_alignment);
+
+ start = max;
+ max = MAX2(dev->dev_info.virtual_address_max, 0x100000000ULL);
+ amdgpu_vamgr_init(&dev->vamgr, start, max,
+ dev->dev_info.virtual_address_alignment);
- amdgpu_vamgr_init(dev->vamgr, dev->dev_info.virtual_address_offset,
- dev->dev_info.virtual_address_max,
+ start = dev->dev_info.high_va_offset;
+ max = MIN2(dev->dev_info.high_va_max, (start & ~0xffffffffULL) +
+ 0x100000000ULL);
+ amdgpu_vamgr_init(&dev->vamgr_high_32, start, max,
dev->dev_info.virtual_address_alignment);
- max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff);
- start = amdgpu_vamgr_find_va(dev->vamgr,
- max - dev->dev_info.virtual_address_offset,
- dev->dev_info.virtual_address_alignment, 0);
- if (start > 0xffffffff)
- goto free_va; /* shouldn't get here */
-
- dev->vamgr_32 = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
- if (dev->vamgr_32 == NULL)
- goto free_va;
- amdgpu_vamgr_init(dev->vamgr_32, start, max,
+ start = max;
+ max = MAX2(dev->dev_info.high_va_max, (start & ~0xffffffffULL) +
+ 0x100000000ULL);
+ amdgpu_vamgr_init(&dev->vamgr_high, start, max,
dev->dev_info.virtual_address_alignment);
+ amdgpu_parse_asic_ids(dev);
+
*major_version = dev->major_version;
*minor_version = dev->minor_version;
*device_handle = dev;
- util_hash_table_set(fd_tab, UINT_TO_PTR(dev->fd), dev);
+ dev->next = fd_list;
+ fd_list = dev;
pthread_mutex_unlock(&fd_mutex);
return 0;
-free_va:
- r = -ENOMEM;
- amdgpu_vamgr_free_va(dev->vamgr, start,
- max - dev->dev_info.virtual_address_offset);
- amdgpu_vamgr_deinit(dev->vamgr);
- free(dev->vamgr);
-
cleanup:
if (dev->fd >= 0)
close(dev->fd);
@@ -299,22 +279,30 @@ cleanup:
return r;
}
-int amdgpu_device_deinitialize(amdgpu_device_handle dev)
+drm_public int amdgpu_device_deinitialize(amdgpu_device_handle dev)
{
amdgpu_device_reference(&dev, NULL);
return 0;
}
-const char *amdgpu_get_marketing_name(amdgpu_device_handle dev)
+drm_public const char *amdgpu_get_marketing_name(amdgpu_device_handle dev)
{
- const struct amdgpu_asic_id_table_t *t = amdgpu_asic_id_table;
+ return dev->marketing_name;
+}
- while (t->did) {
- if ((t->did == dev->info.asic_id) &&
- (t->rid == dev->info.pci_rev_id))
- return t->marketing_name;
- t++;
+drm_public int amdgpu_query_sw_info(amdgpu_device_handle dev,
+ enum amdgpu_sw_info info,
+ void *value)
+{
+ uint32_t *val32 = (uint32_t*)value;
+
+ switch (info) {
+ case amdgpu_sw_info_address32_hi:
+ if (dev->vamgr_high_32.va_max)
+ *val32 = (dev->vamgr_high_32.va_max - 1) >> 32;
+ else
+ *val32 = (dev->vamgr_32.va_max - 1) >> 32;
+ return 0;
}
-
- return NULL;
+ return -EINVAL;
}
diff --git a/amdgpu/amdgpu_gpu_info.c b/amdgpu/amdgpu_gpu_info.c
index 66c7e0e1..777087f2 100644
--- a/amdgpu/amdgpu_gpu_info.c
+++ b/amdgpu/amdgpu_gpu_info.c
@@ -22,10 +22,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <string.h>
@@ -34,8 +30,8 @@
#include "amdgpu_internal.h"
#include "xf86drm.h"
-int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
- unsigned size, void *value)
+drm_public int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
+ unsigned size, void *value)
{
struct drm_amdgpu_info request;
@@ -48,8 +44,8 @@ int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
sizeof(struct drm_amdgpu_info));
}
-int amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id,
- int32_t *result)
+drm_public int amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id,
+ int32_t *result)
{
struct drm_amdgpu_info request;
@@ -63,9 +59,9 @@ int amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id,
sizeof(struct drm_amdgpu_info));
}
-int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset,
- unsigned count, uint32_t instance, uint32_t flags,
- uint32_t *values)
+drm_public int amdgpu_read_mm_registers(amdgpu_device_handle dev,
+ unsigned dword_offset, unsigned count, uint32_t instance,
+ uint32_t flags, uint32_t *values)
{
struct drm_amdgpu_info request;
@@ -82,8 +78,9 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset,
sizeof(struct drm_amdgpu_info));
}
-int amdgpu_query_hw_ip_count(amdgpu_device_handle dev, unsigned type,
- uint32_t *count)
+drm_public int amdgpu_query_hw_ip_count(amdgpu_device_handle dev,
+ unsigned type,
+ uint32_t *count)
{
struct drm_amdgpu_info request;
@@ -97,9 +94,9 @@ int amdgpu_query_hw_ip_count(amdgpu_device_handle dev, unsigned type,
sizeof(struct drm_amdgpu_info));
}
-int amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type,
- unsigned ip_instance,
- struct drm_amdgpu_info_hw_ip *info)
+drm_public int amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type,
+ unsigned ip_instance,
+ struct drm_amdgpu_info_hw_ip *info)
{
struct drm_amdgpu_info request;
@@ -114,9 +111,9 @@ int amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type,
sizeof(struct drm_amdgpu_info));
}
-int amdgpu_query_firmware_version(amdgpu_device_handle dev, unsigned fw_type,
- unsigned ip_instance, unsigned index,
- uint32_t *version, uint32_t *feature)
+drm_public int amdgpu_query_firmware_version(amdgpu_device_handle dev,
+ unsigned fw_type, unsigned ip_instance, unsigned index,
+ uint32_t *version, uint32_t *feature)
{
struct drm_amdgpu_info request;
struct drm_amdgpu_info_firmware firmware = {};
@@ -169,53 +166,57 @@ drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
dev->info.vce_harvest_config = dev->dev_info.vce_harvest_config;
dev->info.pci_rev_id = dev->dev_info.pci_rev;
- for (i = 0; i < (int)dev->info.num_shader_engines; i++) {
- unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
- (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
- AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
+ if (dev->info.family_id < AMDGPU_FAMILY_AI) {
+ for (i = 0; i < (int)dev->info.num_shader_engines; i++) {
+ unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
+ (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
+ AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
- r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
- &dev->info.backend_disable[i]);
- if (r)
- return r;
- /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */
- dev->info.backend_disable[i] =
- (dev->info.backend_disable[i] >> 16) & 0xff;
-
- r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
- &dev->info.pa_sc_raster_cfg[i]);
- if (r)
- return r;
+ r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
+ &dev->info.backend_disable[i]);
+ if (r)
+ return r;
+ /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */
+ dev->info.backend_disable[i] =
+ (dev->info.backend_disable[i] >> 16) & 0xff;
- if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
- r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
- &dev->info.pa_sc_raster_cfg1[i]);
+ r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
+ &dev->info.pa_sc_raster_cfg[i]);
if (r)
return r;
+
+ if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
+ r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
+ &dev->info.pa_sc_raster_cfg1[i]);
+ if (r)
+ return r;
+ }
}
}
- r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
- dev->info.gb_tile_mode);
+ r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
+ &dev->info.gb_addr_cfg);
if (r)
return r;
- if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
- r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
- dev->info.gb_macro_tile_mode);
+ if (dev->info.family_id < AMDGPU_FAMILY_AI) {
+ r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
+ dev->info.gb_tile_mode);
if (r)
return r;
- }
- r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
- &dev->info.gb_addr_cfg);
- if (r)
- return r;
+ if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
+ r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
+ dev->info.gb_macro_tile_mode);
+ if (r)
+ return r;
+ }
- r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
- &dev->info.mc_arb_ramcfg);
- if (r)
- return r;
+ r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
+ &dev->info.mc_arb_ramcfg);
+ if (r)
+ return r;
+ }
dev->info.cu_active_number = dev->dev_info.cu_active_number;
dev->info.cu_ao_mask = dev->dev_info.cu_ao_mask;
@@ -227,21 +228,22 @@ drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
return 0;
}
-int amdgpu_query_gpu_info(amdgpu_device_handle dev,
- struct amdgpu_gpu_info *info)
+drm_public int amdgpu_query_gpu_info(amdgpu_device_handle dev,
+ struct amdgpu_gpu_info *info)
{
- if ((dev == NULL) || (info == NULL))
+ if (!dev || !info)
return -EINVAL;
+
/* Get ASIC info*/
*info = dev->info;
return 0;
}
-int amdgpu_query_heap_info(amdgpu_device_handle dev,
- uint32_t heap,
- uint32_t flags,
- struct amdgpu_heap_info *info)
+drm_public int amdgpu_query_heap_info(amdgpu_device_handle dev,
+ uint32_t heap,
+ uint32_t flags,
+ struct amdgpu_heap_info *info)
{
struct drm_amdgpu_info_vram_gtt vram_gtt_info = {};
int r;
@@ -290,13 +292,13 @@ int amdgpu_query_heap_info(amdgpu_device_handle dev,
return 0;
}
-int amdgpu_query_gds_info(amdgpu_device_handle dev,
- struct amdgpu_gds_resource_info *gds_info)
+drm_public int amdgpu_query_gds_info(amdgpu_device_handle dev,
+ struct amdgpu_gds_resource_info *gds_info)
{
struct drm_amdgpu_info_gds gds_config = {};
int r;
- if (gds_info == NULL)
+ if (!gds_info)
return -EINVAL;
r = amdgpu_query_info(dev, AMDGPU_INFO_GDS_CONFIG,
@@ -314,3 +316,18 @@ int amdgpu_query_gds_info(amdgpu_device_handle dev,
return 0;
}
+
+drm_public int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
+ unsigned size, void *value)
+{
+ struct drm_amdgpu_info request;
+
+ memset(&request, 0, sizeof(request));
+ request.return_pointer = (uintptr_t)value;
+ request.return_size = size;
+ request.query = AMDGPU_INFO_SENSOR;
+ request.sensor_info.type = sensor_type;
+
+ return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+ sizeof(struct drm_amdgpu_info));
+}
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 4f039b68..a340abbd 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -25,10 +25,6 @@
#ifndef _AMDGPU_INTERNAL_H_
#define _AMDGPU_INTERNAL_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <assert.h>
#include <pthread.h>
@@ -36,6 +32,7 @@
#include "xf86atomic.h"
#include "amdgpu.h"
#include "util_double_list.h"
+#include "handle_table.h"
#define AMDGPU_CS_MAX_RINGS 8
/* do not use below macro if b is not power of 2 aligned value */
@@ -53,8 +50,6 @@ struct amdgpu_bo_va_hole {
};
struct amdgpu_bo_va_mgr {
- /* the start virtual address */
- uint64_t va_offset;
uint64_t va_max;
struct list_head va_holes;
pthread_mutex_t bo_va_mutex;
@@ -71,23 +66,29 @@ struct amdgpu_va {
struct amdgpu_device {
atomic_t refcount;
+ struct amdgpu_device *next;
int fd;
int flink_fd;
unsigned major_version;
unsigned minor_version;
+ char *marketing_name;
/** List of buffer handles. Protected by bo_table_mutex. */
- struct util_hash_table *bo_handles;
+ struct handle_table bo_handles;
/** List of buffer GEM flink names. Protected by bo_table_mutex. */
- struct util_hash_table *bo_flink_names;
+ struct handle_table bo_flink_names;
/** This protects all hash tables. */
pthread_mutex_t bo_table_mutex;
struct drm_amdgpu_info_device dev_info;
struct amdgpu_gpu_info info;
- /** The global VA manager for the whole virtual address space */
- struct amdgpu_bo_va_mgr *vamgr;
+ /** The VA manager for the lower virtual address space */
+ struct amdgpu_bo_va_mgr vamgr;
/** The VA manager for the 32bit address space */
- struct amdgpu_bo_va_mgr *vamgr_32;
+ struct amdgpu_bo_va_mgr vamgr_32;
+ /** The VA manager for the high virtual address space */
+ struct amdgpu_bo_va_mgr vamgr_high;
+ /** The VA manager for the 32bit high address space */
+ struct amdgpu_bo_va_mgr vamgr_high_32;
};
struct amdgpu_bo {
@@ -135,19 +136,12 @@ struct amdgpu_semaphore {
* Functions.
*/
-drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo);
-
drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
uint64_t max, uint64_t alignment);
drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
-drm_private uint64_t
-amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
- uint64_t alignment, uint64_t base_required);
-
-drm_private void
-amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va, uint64_t size);
+drm_private void amdgpu_parse_asic_ids(struct amdgpu_device *dev);
drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev);
@@ -179,26 +173,4 @@ static inline bool update_references(atomic_t *dst, atomic_t *src)
return false;
}
-/**
- * Assignment between two amdgpu_bo pointers with reference counting.
- *
- * Usage:
- * struct amdgpu_bo *dst = ... , *src = ...;
- *
- * dst = src;
- * // No reference counting. Only use this when you need to move
- * // a reference from one pointer to another.
- *
- * amdgpu_bo_reference(&dst, src);
- * // Reference counters are updated. dst is decremented and src is
- * // incremented. dst is freed if its reference counter is 0.
- */
-static inline void amdgpu_bo_reference(struct amdgpu_bo **dst,
- struct amdgpu_bo *src)
-{
- if (update_references(&(*dst)->refcount, &src->refcount))
- amdgpu_bo_free_internal(*dst);
- *dst = src;
-}
-
#endif
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 8a707cbc..d25d4216 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -21,10 +21,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@@ -33,26 +29,34 @@
#include "amdgpu_internal.h"
#include "util_math.h"
-int amdgpu_va_range_query(amdgpu_device_handle dev,
- enum amdgpu_gpu_va_range type, uint64_t *start, uint64_t *end)
+drm_public int amdgpu_va_range_query(amdgpu_device_handle dev,
+ enum amdgpu_gpu_va_range type,
+ uint64_t *start, uint64_t *end)
{
- if (type == amdgpu_gpu_va_range_general) {
- *start = dev->dev_info.virtual_address_offset;
- *end = dev->dev_info.virtual_address_max;
- return 0;
- }
- return -EINVAL;
+ if (type != amdgpu_gpu_va_range_general)
+ return -EINVAL;
+
+ *start = dev->dev_info.virtual_address_offset;
+ *end = dev->dev_info.virtual_address_max;
+ return 0;
}
drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
- uint64_t max, uint64_t alignment)
+ uint64_t max, uint64_t alignment)
{
- mgr->va_offset = start;
+ struct amdgpu_bo_va_hole *n;
+
mgr->va_max = max;
mgr->va_alignment = alignment;
list_inithead(&mgr->va_holes);
pthread_mutex_init(&mgr->bo_va_mutex, NULL);
+ pthread_mutex_lock(&mgr->bo_va_mutex);
+ n = calloc(1, sizeof(struct amdgpu_bo_va_hole));
+ n->size = mgr->va_max - start;
+ n->offset = start;
+ list_add(&n->list, &mgr->va_holes);
+ pthread_mutex_unlock(&mgr->bo_va_mutex);
}
drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
@@ -65,13 +69,14 @@ drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
pthread_mutex_destroy(&mgr->bo_va_mutex);
}
-drm_private uint64_t
+static drm_private uint64_t
amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
uint64_t alignment, uint64_t base_required)
{
struct amdgpu_bo_va_hole *hole, *n;
uint64_t offset = 0, waste = 0;
+
alignment = MAX2(alignment, mgr->va_alignment);
size = ALIGN(size, mgr->va_alignment);
@@ -79,12 +84,10 @@ amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
return AMDGPU_INVALID_VA_ADDRESS;
pthread_mutex_lock(&mgr->bo_va_mutex);
- /* TODO: using more appropriate way to track the holes */
- /* first look for a hole */
- LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) {
+ LIST_FOR_EACH_ENTRY_SAFE_REV(hole, n, &mgr->va_holes, list) {
if (base_required) {
- if(hole->offset > base_required ||
- (hole->offset + hole->size) < (base_required + size))
+ if (hole->offset > base_required ||
+ (hole->offset + hole->size) < (base_required + size))
continue;
waste = base_required - hole->offset;
offset = base_required;
@@ -123,41 +126,14 @@ amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
}
}
- if (base_required) {
- if (base_required < mgr->va_offset) {
- pthread_mutex_unlock(&mgr->bo_va_mutex);
- return AMDGPU_INVALID_VA_ADDRESS;
- }
- offset = mgr->va_offset;
- waste = base_required - mgr->va_offset;
- } else {
- offset = mgr->va_offset;
- waste = offset % alignment;
- waste = waste ? alignment - waste : 0;
- }
-
- if (offset + waste + size > mgr->va_max) {
- pthread_mutex_unlock(&mgr->bo_va_mutex);
- return AMDGPU_INVALID_VA_ADDRESS;
- }
-
- if (waste) {
- n = calloc(1, sizeof(struct amdgpu_bo_va_hole));
- n->size = waste;
- n->offset = offset;
- list_add(&n->list, &mgr->va_holes);
- }
-
- offset += waste;
- mgr->va_offset += size + waste;
pthread_mutex_unlock(&mgr->bo_va_mutex);
- return offset;
+ return AMDGPU_INVALID_VA_ADDRESS;
}
-drm_private void
+static drm_private void
amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va, uint64_t size)
{
- struct amdgpu_bo_va_hole *hole;
+ struct amdgpu_bo_va_hole *hole, *next;
if (va == AMDGPU_INVALID_VA_ADDRESS)
return;
@@ -165,80 +141,77 @@ amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va, uint64_t size)
size = ALIGN(size, mgr->va_alignment);
pthread_mutex_lock(&mgr->bo_va_mutex);
- if ((va + size) == mgr->va_offset) {
- mgr->va_offset = va;
- /* Delete uppermost hole if it reaches the new top */
- if (!LIST_IS_EMPTY(&mgr->va_holes)) {
- hole = container_of(mgr->va_holes.next, hole, list);
- if ((hole->offset + hole->size) == va) {
- mgr->va_offset = hole->offset;
+ hole = container_of(&mgr->va_holes, hole, list);
+ LIST_FOR_EACH_ENTRY(next, &mgr->va_holes, list) {
+ if (next->offset < va)
+ break;
+ hole = next;
+ }
+
+ if (&hole->list != &mgr->va_holes) {
+ /* Grow upper hole if it's adjacent */
+ if (hole->offset == (va + size)) {
+ hole->offset = va;
+ hole->size += size;
+ /* Merge lower hole if it's adjacent */
+ if (next != hole &&
+ &next->list != &mgr->va_holes &&
+ (next->offset + next->size) == va) {
+ next->size += hole->size;
list_del(&hole->list);
free(hole);
}
- }
- } else {
- struct amdgpu_bo_va_hole *next;
-
- hole = container_of(&mgr->va_holes, hole, list);
- LIST_FOR_EACH_ENTRY(next, &mgr->va_holes, list) {
- if (next->offset < va)
- break;
- hole = next;
- }
-
- if (&hole->list != &mgr->va_holes) {
- /* Grow upper hole if it's adjacent */
- if (hole->offset == (va + size)) {
- hole->offset = va;
- hole->size += size;
- /* Merge lower hole if it's adjacent */
- if (next != hole
- && &next->list != &mgr->va_holes
- && (next->offset + next->size) == va) {
- next->size += hole->size;
- list_del(&hole->list);
- free(hole);
- }
- goto out;
- }
- }
-
- /* Grow lower hole if it's adjacent */
- if (next != hole && &next->list != &mgr->va_holes &&
- (next->offset + next->size) == va) {
- next->size += size;
goto out;
}
+ }
- /* FIXME on allocation failure we just lose virtual address space
- * maybe print a warning
- */
- next = calloc(1, sizeof(struct amdgpu_bo_va_hole));
- if (next) {
- next->size = size;
- next->offset = va;
- list_add(&next->list, &hole->list);
- }
+ /* Grow lower hole if it's adjacent */
+ if (next != hole && &next->list != &mgr->va_holes &&
+ (next->offset + next->size) == va) {
+ next->size += size;
+ goto out;
+ }
+
+ /* FIXME on allocation failure we just lose virtual address space
+ * maybe print a warning
+ */
+ next = calloc(1, sizeof(struct amdgpu_bo_va_hole));
+ if (next) {
+ next->size = size;
+ next->offset = va;
+ list_add(&next->list, &hole->list);
}
+
out:
pthread_mutex_unlock(&mgr->bo_va_mutex);
}
-int amdgpu_va_range_alloc(amdgpu_device_handle dev,
- enum amdgpu_gpu_va_range va_range_type,
- uint64_t size,
- uint64_t va_base_alignment,
- uint64_t va_base_required,
- uint64_t *va_base_allocated,
- amdgpu_va_handle *va_range_handle,
- uint64_t flags)
+drm_public int amdgpu_va_range_alloc(amdgpu_device_handle dev,
+ enum amdgpu_gpu_va_range va_range_type,
+ uint64_t size,
+ uint64_t va_base_alignment,
+ uint64_t va_base_required,
+ uint64_t *va_base_allocated,
+ amdgpu_va_handle *va_range_handle,
+ uint64_t flags)
{
struct amdgpu_bo_va_mgr *vamgr;
- if (flags & AMDGPU_VA_RANGE_32_BIT)
- vamgr = dev->vamgr_32;
- else
- vamgr = dev->vamgr;
+ /* Clear the flag when the high VA manager is not initialized */
+ if (flags & AMDGPU_VA_RANGE_HIGH && !dev->vamgr_high_32.va_max)
+ flags &= ~AMDGPU_VA_RANGE_HIGH;
+
+ if (flags & AMDGPU_VA_RANGE_HIGH) {
+ if (flags & AMDGPU_VA_RANGE_32_BIT)
+ vamgr = &dev->vamgr_high_32;
+ else
+ vamgr = &dev->vamgr_high;
+ } else {
+ if (flags & AMDGPU_VA_RANGE_32_BIT)
+ vamgr = &dev->vamgr_32;
+ else
+ vamgr = &dev->vamgr;
+ }
va_base_alignment = MAX2(va_base_alignment, vamgr->va_alignment);
size = ALIGN(size, vamgr->va_alignment);
@@ -249,7 +222,10 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev,
if (!(flags & AMDGPU_VA_RANGE_32_BIT) &&
(*va_base_allocated == AMDGPU_INVALID_VA_ADDRESS)) {
/* fallback to 32bit address */
- vamgr = dev->vamgr_32;
+ if (flags & AMDGPU_VA_RANGE_HIGH)
+ vamgr = &dev->vamgr_high_32;
+ else
+ vamgr = &dev->vamgr_32;
*va_base_allocated = amdgpu_vamgr_find_va(vamgr, size,
va_base_alignment, va_base_required);
}
@@ -274,7 +250,7 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev,
return 0;
}
-int amdgpu_va_range_free(amdgpu_va_handle va_range_handle)
+drm_public int amdgpu_va_range_free(amdgpu_va_handle va_range_handle)
{
if(!va_range_handle || !va_range_handle->address)
return 0;
diff --git a/amdgpu/amdgpu_vm.c b/amdgpu/amdgpu_vm.c
new file mode 100644
index 00000000..7e6e28f0
--- /dev/null
+++ b/amdgpu/amdgpu_vm.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017 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 "amdgpu.h"
+#include "amdgpu_drm.h"
+#include "xf86drm.h"
+#include "amdgpu_internal.h"
+
+drm_public int amdgpu_vm_reserve_vmid(amdgpu_device_handle dev, uint32_t flags)
+{
+ union drm_amdgpu_vm vm;
+
+ vm.in.op = AMDGPU_VM_OP_RESERVE_VMID;
+ vm.in.flags = flags;
+
+ return drmCommandWriteRead(dev->fd, DRM_AMDGPU_VM,
+ &vm, sizeof(vm));
+}
+
+drm_public int amdgpu_vm_unreserve_vmid(amdgpu_device_handle dev,
+ uint32_t flags)
+{
+ union drm_amdgpu_vm vm;
+
+ vm.in.op = AMDGPU_VM_OP_UNRESERVE_VMID;
+ vm.in.flags = flags;
+
+ return drmCommandWriteRead(dev->fd, DRM_AMDGPU_VM,
+ &vm, sizeof(vm));
+}
diff --git a/amdgpu/handle_table.c b/amdgpu/handle_table.c
new file mode 100644
index 00000000..4fdd29d3
--- /dev/null
+++ b/amdgpu/handle_table.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2018 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 <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include "handle_table.h"
+#include "util_math.h"
+
+drm_private int handle_table_insert(struct handle_table *table, uint32_t key,
+ void *value)
+{
+ if (key >= table->max_key) {
+ uint32_t alignment = sysconf(_SC_PAGESIZE) / sizeof(void*);
+ uint32_t max_key = ALIGN(key + 1, alignment);
+ void **values;
+
+ values = realloc(table->values, max_key * sizeof(void *));
+ if (!values)
+ return -ENOMEM;
+
+ memset(values + table->max_key, 0, (max_key - table->max_key) *
+ sizeof(void *));
+
+ table->max_key = max_key;
+ table->values = values;
+ }
+ table->values[key] = value;
+ return 0;
+}
+
+drm_private void handle_table_remove(struct handle_table *table, uint32_t key)
+{
+ if (key < table->max_key)
+ table->values[key] = NULL;
+}
+
+drm_private void *handle_table_lookup(struct handle_table *table, uint32_t key)
+{
+ if (key < table->max_key)
+ return table->values[key];
+ else
+ return NULL;
+}
+
+drm_private void handle_table_fini(struct handle_table *table)
+{
+ free(table->values);
+ table->max_key = 0;
+ table->values = NULL;
+}
diff --git a/amdgpu/handle_table.h b/amdgpu/handle_table.h
new file mode 100644
index 00000000..461193f6
--- /dev/null
+++ b/amdgpu/handle_table.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 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 _HANDLE_TABLE_H_
+#define _HANDLE_TABLE_H_
+
+#include <stdint.h>
+#include "libdrm_macros.h"
+
+struct handle_table {
+ uint32_t max_key;
+ void **values;
+};
+
+drm_private int handle_table_insert(struct handle_table *table, uint32_t key,
+ void *value);
+drm_private void handle_table_remove(struct handle_table *table, uint32_t key);
+drm_private void *handle_table_lookup(struct handle_table *table, uint32_t key);
+drm_private void handle_table_fini(struct handle_table *table);
+
+#endif /* _HANDLE_TABLE_H_ */
diff --git a/amdgpu/meson.build b/amdgpu/meson.build
new file mode 100644
index 00000000..7c8ccc7e
--- /dev/null
+++ b/amdgpu/meson.build
@@ -0,0 +1,65 @@
+# 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.
+
+
+datadir_amdgpu = join_paths(get_option('prefix'), get_option('datadir'), 'libdrm')
+
+libdrm_amdgpu = shared_library(
+ 'drm_amdgpu',
+ [
+ files(
+ 'amdgpu_asic_id.c', 'amdgpu_bo.c', 'amdgpu_cs.c', 'amdgpu_device.c',
+ 'amdgpu_gpu_info.c', 'amdgpu_vamgr.c', 'amdgpu_vm.c', 'handle_table.c',
+ ),
+ config_file,
+ ],
+ c_args : [
+ libdrm_c_args,
+ '-DAMDGPU_ASIC_ID_TABLE="@0@"'.format(join_paths(datadir_amdgpu, 'amdgpu.ids')),
+ ],
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ dependencies : [dep_pthread_stubs, dep_atomic_ops],
+ version : '1.0.0',
+ install : true,
+)
+
+install_headers('amdgpu.h', subdir : 'libdrm')
+
+pkg.generate(
+ name : 'libdrm_amdgpu',
+ libraries : libdrm_amdgpu,
+ subdirs : ['.', 'libdrm'],
+ version : meson.project_version(),
+ requires_private : 'libdrm',
+ description : 'Userspace interface to kernel DRM services for amdgpu',
+)
+
+ext_libdrm_amdgpu = declare_dependency(
+ link_with : [libdrm, libdrm_amdgpu],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+test(
+ 'amdgpu-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('amdgpu-symbol-check'), libdrm_amdgpu]
+)
diff --git a/amdgpu/util_hash.c b/amdgpu/util_hash.c
deleted file mode 100644
index 87cb671b..00000000
--- a/amdgpu/util_hash.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 VMware, Inc.
- * 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 VMWARE 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.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Zack Rusin <zackr@vmware.com>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "util_hash.h"
-
-#include <stdlib.h>
-#include <assert.h>
-
-#define MAX(a, b) ((a > b) ? (a) : (b))
-
-static const int MinNumBits = 4;
-
-static const unsigned char prime_deltas[] = {
- 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
- 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
-};
-
-static int primeForNumBits(int numBits)
-{
- return (1 << numBits) + prime_deltas[numBits];
-}
-
-/* Returns the smallest integer n such that
- primeForNumBits(n) >= hint.
-*/
-static int countBits(int hint)
-{
- int numBits = 0;
- int bits = hint;
-
- while (bits > 1) {
- bits >>= 1;
- numBits++;
- }
-
- if (numBits >= (int)sizeof(prime_deltas)) {
- numBits = sizeof(prime_deltas) - 1;
- } else if (primeForNumBits(numBits) < hint) {
- ++numBits;
- }
- return numBits;
-}
-
-struct util_node {
- struct util_node *next;
- unsigned key;
- void *value;
-};
-
-struct util_hash_data {
- struct util_node *fakeNext;
- struct util_node **buckets;
- int size;
- int nodeSize;
- short userNumBits;
- short numBits;
- int numBuckets;
-};
-
-struct util_hash {
- union {
- struct util_hash_data *d;
- struct util_node *e;
- } data;
-};
-
-static void *util_data_allocate_node(struct util_hash_data *hash)
-{
- return malloc(hash->nodeSize);
-}
-
-static void util_free_node(struct util_node *node)
-{
- free(node);
-}
-
-static struct util_node *
-util_hash_create_node(struct util_hash *hash,
- unsigned akey, void *avalue,
- struct util_node **anextNode)
-{
- struct util_node *node = util_data_allocate_node(hash->data.d);
-
- if (!node)
- return NULL;
-
- node->key = akey;
- node->value = avalue;
-
- node->next = (struct util_node*)(*anextNode);
- *anextNode = node;
- ++hash->data.d->size;
- return node;
-}
-
-static void util_data_rehash(struct util_hash_data *hash, int hint)
-{
- if (hint < 0) {
- hint = countBits(-hint);
- if (hint < MinNumBits)
- hint = MinNumBits;
- hash->userNumBits = (short)hint;
- while (primeForNumBits(hint) < (hash->size >> 1))
- ++hint;
- } else if (hint < MinNumBits) {
- hint = MinNumBits;
- }
-
- if (hash->numBits != hint) {
- struct util_node *e = (struct util_node *)(hash);
- struct util_node **oldBuckets = hash->buckets;
- int oldNumBuckets = hash->numBuckets;
- int i = 0;
-
- hash->numBits = (short)hint;
- hash->numBuckets = primeForNumBits(hint);
- hash->buckets = malloc(sizeof(struct util_node*) * hash->numBuckets);
- for (i = 0; i < hash->numBuckets; ++i)
- hash->buckets[i] = e;
-
- for (i = 0; i < oldNumBuckets; ++i) {
- struct util_node *firstNode = oldBuckets[i];
- while (firstNode != e) {
- unsigned h = firstNode->key;
- struct util_node *lastNode = firstNode;
- struct util_node *afterLastNode;
- struct util_node **beforeFirstNode;
-
- while (lastNode->next != e && lastNode->next->key == h)
- lastNode = lastNode->next;
-
- afterLastNode = lastNode->next;
- beforeFirstNode = &hash->buckets[h % hash->numBuckets];
- while (*beforeFirstNode != e)
- beforeFirstNode = &(*beforeFirstNode)->next;
- lastNode->next = *beforeFirstNode;
- *beforeFirstNode = firstNode;
- firstNode = afterLastNode;
- }
- }
- free(oldBuckets);
- }
-}
-
-static void util_data_might_grow(struct util_hash_data *hash)
-{
- if (hash->size >= hash->numBuckets)
- util_data_rehash(hash, hash->numBits + 1);
-}
-
-static void util_data_has_shrunk(struct util_hash_data *hash)
-{
- if (hash->size <= (hash->numBuckets >> 3) &&
- hash->numBits > hash->userNumBits) {
- int max = MAX(hash->numBits-2, hash->userNumBits);
- util_data_rehash(hash, max);
- }
-}
-
-static struct util_node *util_data_first_node(struct util_hash_data *hash)
-{
- struct util_node *e = (struct util_node *)(hash);
- struct util_node **bucket = hash->buckets;
- int n = hash->numBuckets;
- while (n--) {
- if (*bucket != e)
- return *bucket;
- ++bucket;
- }
- return e;
-}
-
-static struct util_node **util_hash_find_node(struct util_hash *hash, unsigned akey)
-{
- struct util_node **node;
-
- if (hash->data.d->numBuckets) {
- node = (struct util_node **)(&hash->data.d->buckets[akey % hash->data.d->numBuckets]);
- assert(*node == hash->data.e || (*node)->next);
- while (*node != hash->data.e && (*node)->key != akey)
- node = &(*node)->next;
- } else {
- node = (struct util_node **)((const struct util_node * const *)(&hash->data.e));
- }
- return node;
-}
-
-drm_private struct util_hash_iter
-util_hash_insert(struct util_hash *hash, unsigned key, void *data)
-{
- util_data_might_grow(hash->data.d);
-
- {
- struct util_node **nextNode = util_hash_find_node(hash, key);
- struct util_node *node = util_hash_create_node(hash, key, data, nextNode);
- if (!node) {
- struct util_hash_iter null_iter = {hash, 0};
- return null_iter;
- }
-
- {
- struct util_hash_iter iter = {hash, node};
- return iter;
- }
- }
-}
-
-drm_private struct util_hash *util_hash_create(void)
-{
- struct util_hash *hash = malloc(sizeof(struct util_hash));
- if (!hash)
- return NULL;
-
- hash->data.d = malloc(sizeof(struct util_hash_data));
- if (!hash->data.d) {
- free(hash);
- return NULL;
- }
-
- hash->data.d->fakeNext = 0;
- hash->data.d->buckets = 0;
- hash->data.d->size = 0;
- hash->data.d->nodeSize = sizeof(struct util_node);
- hash->data.d->userNumBits = (short)MinNumBits;
- hash->data.d->numBits = 0;
- hash->data.d->numBuckets = 0;
-
- return hash;
-}
-
-drm_private void util_hash_delete(struct util_hash *hash)
-{
- struct util_node *e_for_x = (struct util_node *)(hash->data.d);
- struct util_node **bucket = (struct util_node **)(hash->data.d->buckets);
- int n = hash->data.d->numBuckets;
- while (n--) {
- struct util_node *cur = *bucket++;
- while (cur != e_for_x) {
- struct util_node *next = cur->next;
- util_free_node(cur);
- cur = next;
- }
- }
- free(hash->data.d->buckets);
- free(hash->data.d);
- free(hash);
-}
-
-drm_private struct util_hash_iter
-util_hash_find(struct util_hash *hash, unsigned key)
-{
- struct util_node **nextNode = util_hash_find_node(hash, key);
- struct util_hash_iter iter = {hash, *nextNode};
- return iter;
-}
-
-drm_private unsigned util_hash_iter_key(struct util_hash_iter iter)
-{
- if (!iter.node || iter.hash->data.e == iter.node)
- return 0;
- return iter.node->key;
-}
-
-drm_private void *util_hash_iter_data(struct util_hash_iter iter)
-{
- if (!iter.node || iter.hash->data.e == iter.node)
- return 0;
- return iter.node->value;
-}
-
-static struct util_node *util_hash_data_next(struct util_node *node)
-{
- union {
- struct util_node *next;
- struct util_node *e;
- struct util_hash_data *d;
- } a;
- int start;
- struct util_node **bucket;
- int n;
-
- a.next = node->next;
- if (!a.next) {
- /* iterating beyond the last element */
- return 0;
- }
- if (a.next->next)
- return a.next;
-
- start = (node->key % a.d->numBuckets) + 1;
- bucket = a.d->buckets + start;
- n = a.d->numBuckets - start;
- while (n--) {
- if (*bucket != a.e)
- return *bucket;
- ++bucket;
- }
- return a.e;
-}
-
-drm_private struct util_hash_iter
-util_hash_iter_next(struct util_hash_iter iter)
-{
- struct util_hash_iter next = {iter.hash, util_hash_data_next(iter.node)};
- return next;
-}
-
-drm_private int util_hash_iter_is_null(struct util_hash_iter iter)
-{
- if (!iter.node || iter.node == iter.hash->data.e)
- return 1;
- return 0;
-}
-
-drm_private void *util_hash_take(struct util_hash *hash, unsigned akey)
-{
- struct util_node **node = util_hash_find_node(hash, akey);
- if (*node != hash->data.e) {
- void *t = (*node)->value;
- struct util_node *next = (*node)->next;
- util_free_node(*node);
- *node = next;
- --hash->data.d->size;
- util_data_has_shrunk(hash->data.d);
- return t;
- }
- return 0;
-}
-
-drm_private struct util_hash_iter util_hash_first_node(struct util_hash *hash)
-{
- struct util_hash_iter iter = {hash, util_data_first_node(hash->data.d)};
- return iter;
-}
-
-drm_private struct util_hash_iter
-util_hash_erase(struct util_hash *hash, struct util_hash_iter iter)
-{
- struct util_hash_iter ret = iter;
- struct util_node *node = iter.node;
- struct util_node **node_ptr;
-
- if (node == hash->data.e)
- return iter;
-
- ret = util_hash_iter_next(ret);
- node_ptr = (struct util_node**)(&hash->data.d->buckets[node->key % hash->data.d->numBuckets]);
- while (*node_ptr != node)
- node_ptr = &(*node_ptr)->next;
- *node_ptr = node->next;
- util_free_node(node);
- --hash->data.d->size;
- return ret;
-}
diff --git a/amdgpu/util_hash.h b/amdgpu/util_hash.h
deleted file mode 100644
index 01a4779b..00000000
--- a/amdgpu/util_hash.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 VMware, Inc.
- * 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 VMWARE 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.
- *
- **************************************************************************/
-
-/**
- * @file
- * Hash implementation.
- *
- * This file provides a hash implementation that is capable of dealing
- * with collisions. It stores colliding entries in linked list. All
- * functions operating on the hash return an iterator. The iterator
- * itself points to the collision list. If there wasn't any collision
- * the list will have just one entry, otherwise client code should
- * iterate over the entries to find the exact entry among ones that
- * had the same key (e.g. memcmp could be used on the data to check
- * that)
- *
- * @author Zack Rusin <zackr@vmware.com>
- */
-
-#ifndef UTIL_HASH_H
-#define UTIL_HASH_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdbool.h>
-
-#include "libdrm_macros.h"
-
-struct util_hash;
-struct util_node;
-
-struct util_hash_iter {
- struct util_hash *hash;
- struct util_node *node;
-};
-
-
-drm_private struct util_hash *util_hash_create(void);
-drm_private void util_hash_delete(struct util_hash *hash);
-
-
-/**
- * Adds a data with the given key to the hash. If entry with the given
- * key is already in the hash, this current entry is instered before it
- * in the collision list.
- * Function returns iterator pointing to the inserted item in the hash.
- */
-drm_private struct util_hash_iter
-util_hash_insert(struct util_hash *hash, unsigned key, void *data);
-
-/**
- * Removes the item pointed to by the current iterator from the hash.
- * Note that the data itself is not erased and if it was a malloc'ed pointer
- * it will have to be freed after calling this function by the callee.
- * Function returns iterator pointing to the item after the removed one in
- * the hash.
- */
-drm_private struct util_hash_iter
-util_hash_erase(struct util_hash *hash, struct util_hash_iter iter);
-
-drm_private void *util_hash_take(struct util_hash *hash, unsigned key);
-
-
-drm_private struct util_hash_iter util_hash_first_node(struct util_hash *hash);
-
-/**
- * Return an iterator pointing to the first entry in the collision list.
- */
-drm_private struct util_hash_iter
-util_hash_find(struct util_hash *hash, unsigned key);
-
-
-drm_private int util_hash_iter_is_null(struct util_hash_iter iter);
-drm_private unsigned util_hash_iter_key(struct util_hash_iter iter);
-drm_private void *util_hash_iter_data(struct util_hash_iter iter);
-
-
-drm_private struct util_hash_iter
-util_hash_iter_next(struct util_hash_iter iter);
-
-#endif
diff --git a/amdgpu/util_hash_table.c b/amdgpu/util_hash_table.c
deleted file mode 100644
index fa7f6eab..00000000
--- a/amdgpu/util_hash_table.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 VMware, Inc.
- * 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 VMWARE 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.
- *
- **************************************************************************/
-
-/**
- * @file
- * General purpose hash table implementation.
- *
- * Just uses the util_hash for now, but it might be better switch to a linear
- * probing hash table implementation at some point -- as it is said they have
- * better lookup and cache performance and it appears to be possible to write
- * a lock-free implementation of such hash tables .
- *
- * @author José Fonseca <jfonseca@vmware.com>
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "util_hash_table.h"
-#include "util_hash.h"
-
-#include <stdlib.h>
-#include <assert.h>
-
-struct util_hash_table
-{
- struct util_hash *head;
-
- /** Hash function */
- unsigned (*make_hash)(void *key);
-
- /** Compare two keys */
- int (*compare)(void *key1, void *key2);
-};
-
-struct util_hash_table_item
-{
- void *key;
- void *value;
-};
-
-
-static struct util_hash_table_item *
-util_hash_table_item(struct util_hash_iter iter)
-{
- return (struct util_hash_table_item *)util_hash_iter_data(iter);
-}
-
-drm_private struct util_hash_table *
-util_hash_table_create(unsigned (*hash)(void *key),
- int (*compare)(void *key1, void *key2))
-{
- struct util_hash_table *ht;
-
- ht = malloc(sizeof(struct util_hash_table));
- if(!ht)
- return NULL;
-
- ht->head = util_hash_create();
- if(!ht->head) {
- free(ht);
- return NULL;
- }
-
- ht->make_hash = hash;
- ht->compare = compare;
-
- return ht;
-}
-
-static struct util_hash_iter
-util_hash_table_find_iter(struct util_hash_table *ht,
- void *key, unsigned key_hash)
-{
- struct util_hash_iter iter;
- struct util_hash_table_item *item;
-
- iter = util_hash_find(ht->head, key_hash);
- while (!util_hash_iter_is_null(iter)) {
- item = (struct util_hash_table_item *)util_hash_iter_data(iter);
- if (!ht->compare(item->key, key))
- break;
- iter = util_hash_iter_next(iter);
- }
-
- return iter;
-}
-
-static struct util_hash_table_item *
-util_hash_table_find_item(struct util_hash_table *ht,
- void *key, unsigned key_hash)
-{
- struct util_hash_iter iter;
- struct util_hash_table_item *item;
-
- iter = util_hash_find(ht->head, key_hash);
- while (!util_hash_iter_is_null(iter)) {
- item = (struct util_hash_table_item *)util_hash_iter_data(iter);
- if (!ht->compare(item->key, key))
- return item;
- iter = util_hash_iter_next(iter);
- }
-
- return NULL;
-}
-
-drm_private void
-util_hash_table_set(struct util_hash_table *ht, void *key, void *value)
-{
- unsigned key_hash;
- struct util_hash_table_item *item;
- struct util_hash_iter iter;
-
- assert(ht);
- if (!ht)
- return;
-
- key_hash = ht->make_hash(key);
-
- item = util_hash_table_find_item(ht, key, key_hash);
- if(item) {
- /* TODO: key/value destruction? */
- item->value = value;
- return;
- }
-
- item = malloc(sizeof(struct util_hash_table_item));
- if(!item)
- return;
-
- item->key = key;
- item->value = value;
-
- iter = util_hash_insert(ht->head, key_hash, item);
- if(util_hash_iter_is_null(iter)) {
- free(item);
- return;
- }
-}
-
-drm_private void *util_hash_table_get(struct util_hash_table *ht, void *key)
-{
- unsigned key_hash;
- struct util_hash_table_item *item;
-
- assert(ht);
- if (!ht)
- return NULL;
-
- key_hash = ht->make_hash(key);
-
- item = util_hash_table_find_item(ht, key, key_hash);
- if(!item)
- return NULL;
-
- return item->value;
-}
-
-drm_private void util_hash_table_remove(struct util_hash_table *ht, void *key)
-{
- unsigned key_hash;
- struct util_hash_iter iter;
- struct util_hash_table_item *item;
-
- assert(ht);
- if (!ht)
- return;
-
- key_hash = ht->make_hash(key);
-
- iter = util_hash_table_find_iter(ht, key, key_hash);
- if(util_hash_iter_is_null(iter))
- return;
-
- item = util_hash_table_item(iter);
- assert(item);
- free(item);
-
- util_hash_erase(ht->head, iter);
-}
-
-drm_private void util_hash_table_clear(struct util_hash_table *ht)
-{
- struct util_hash_iter iter;
- struct util_hash_table_item *item;
-
- assert(ht);
- if (!ht)
- return;
-
- iter = util_hash_first_node(ht->head);
- while (!util_hash_iter_is_null(iter)) {
- item = (struct util_hash_table_item *)util_hash_take(ht->head, util_hash_iter_key(iter));
- free(item);
- iter = util_hash_first_node(ht->head);
- }
-}
-
-drm_private void util_hash_table_foreach(struct util_hash_table *ht,
- void (*callback)(void *key, void *value, void *data),
- void *data)
-{
- struct util_hash_iter iter;
- struct util_hash_table_item *item;
-
- assert(ht);
- if (!ht)
- return;
-
- iter = util_hash_first_node(ht->head);
- while (!util_hash_iter_is_null(iter)) {
- item = (struct util_hash_table_item *)util_hash_iter_data(iter);
- callback(item->key, item->value, data);
- iter = util_hash_iter_next(iter);
- }
-}
-
-drm_private void util_hash_table_destroy(struct util_hash_table *ht)
-{
- struct util_hash_iter iter;
- struct util_hash_table_item *item;
-
- assert(ht);
- if (!ht)
- return;
-
- iter = util_hash_first_node(ht->head);
- while (!util_hash_iter_is_null(iter)) {
- item = (struct util_hash_table_item *)util_hash_iter_data(iter);
- free(item);
- iter = util_hash_iter_next(iter);
- }
-
- util_hash_delete(ht->head);
- free(ht);
-}
diff --git a/amdgpu/util_hash_table.h b/amdgpu/util_hash_table.h
deleted file mode 100644
index e0001289..00000000
--- a/amdgpu/util_hash_table.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 VMware, Inc.
- * 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 VMWARE 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.
- *
- **************************************************************************/
-
-/**
- * General purpose hash table.
- *
- * @author José Fonseca <jfonseca@vmware.com>
- */
-
-#ifndef U_HASH_TABLE_H_
-#define U_HASH_TABLE_H_
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "libdrm_macros.h"
-
-/**
- * Generic purpose hash table.
- */
-struct util_hash_table;
-
-/**
- * Create an hash table.
- *
- * @param hash hash function
- * @param compare should return 0 for two equal keys.
- */
-drm_private struct util_hash_table *
-util_hash_table_create(unsigned (*hash)(void *key),
- int (*compare)(void *key1, void *key2));
-
-drm_private void
-util_hash_table_set(struct util_hash_table *ht, void *key, void *value);
-
-drm_private void *util_hash_table_get(struct util_hash_table *ht, void *key);
-
-drm_private void util_hash_table_remove(struct util_hash_table *ht, void *key);
-
-drm_private void util_hash_table_clear(struct util_hash_table *ht);
-
-drm_private void util_hash_table_foreach(struct util_hash_table *ht,
- void (*callback)(void *key, void *value, void *data),
- void *data);
-
-drm_private void util_hash_table_destroy(struct util_hash_table *ht);
-
-#endif /* U_HASH_TABLE_H_ */
diff --git a/android/gralloc_handle.h b/android/gralloc_handle.h
new file mode 100644
index 00000000..d3d975ee
--- /dev/null
+++ b/android/gralloc_handle.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright (C) 2010-2011 LunarG Inc.
+ * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
+ * Copyright (C) 2018 Collabora, Robert Foss <robert.foss@collabora.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __ANDROID_GRALLOC_HANDLE_H__
+#define __ANDROID_GRALLOC_HANDLE_H__
+
+#include <cutils/native_handle.h>
+#include <stdint.h>
+
+/* support users of drm_gralloc/gbm_gralloc */
+#define gralloc_gbm_handle_t gralloc_handle_t
+#define gralloc_drm_handle_t gralloc_handle_t
+
+struct gralloc_handle_t {
+ native_handle_t base;
+
+ /* dma-buf file descriptor
+ * Must be located first since, native_handle_t is allocated
+ * using native_handle_create(), which allocates space for
+ * sizeof(native_handle_t) + sizeof(int) * (numFds + numInts)
+ * numFds = GRALLOC_HANDLE_NUM_FDS
+ * numInts = GRALLOC_HANDLE_NUM_INTS
+ * Where numFds represents the number of FDs and
+ * numInts represents the space needed for the
+ * remainder of this struct.
+ * And the FDs are expected to be found first following
+ * native_handle_t.
+ */
+ int prime_fd;
+
+ /* api variables */
+ uint32_t magic; /* differentiate between allocator impls */
+ uint32_t version; /* api version */
+
+ uint32_t width; /* width of buffer in pixels */
+ uint32_t height; /* height of buffer in pixels */
+ uint32_t format; /* pixel format (Android) */
+ uint32_t usage; /* android libhardware usage flags */
+
+ uint32_t stride; /* the stride in bytes */
+ int data_owner; /* owner of data (for validation) */
+ uint64_t modifier __attribute__((aligned(8))); /* buffer modifiers */
+
+ union {
+ void *data; /* pointer to struct gralloc_gbm_bo_t */
+ uint64_t reserved;
+ } __attribute__((aligned(8)));
+};
+
+#define GRALLOC_HANDLE_VERSION 4
+#define GRALLOC_HANDLE_MAGIC 0x60585350
+#define GRALLOC_HANDLE_NUM_FDS 1
+#define GRALLOC_HANDLE_NUM_INTS ( \
+ ((sizeof(struct gralloc_handle_t) - sizeof(native_handle_t))/sizeof(int)) \
+ - GRALLOC_HANDLE_NUM_FDS)
+
+static inline struct gralloc_handle_t *gralloc_handle(buffer_handle_t handle)
+{
+ return (struct gralloc_handle_t *)handle;
+}
+
+/**
+ * Create a buffer handle.
+ */
+static inline native_handle_t *gralloc_handle_create(int32_t width,
+ int32_t height,
+ int32_t hal_format,
+ int32_t usage)
+{
+ struct gralloc_handle_t *handle;
+ native_handle_t *nhandle = native_handle_create(GRALLOC_HANDLE_NUM_FDS,
+ GRALLOC_HANDLE_NUM_INTS);
+
+ if (!nhandle)
+ return NULL;
+
+ handle = gralloc_handle(nhandle);
+ handle->magic = GRALLOC_HANDLE_MAGIC;
+ handle->version = GRALLOC_HANDLE_VERSION;
+ handle->width = width;
+ handle->height = height;
+ handle->format = hal_format;
+ handle->usage = usage;
+ handle->prime_fd = -1;
+
+ return nhandle;
+}
+
+#endif
diff --git a/autogen.sh b/autogen.sh
index d82ab180..13d6991e 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -6,15 +6,15 @@ test -z "$srcdir" && srcdir=.
ORIGDIR=`pwd`
cd "$srcdir"
-autoreconf --force --verbose --install || exit 1
-cd "$ORIGDIR" || exit $?
-
-git config --local --get format.subjectPrefix ||
+git config --local --get format.subjectPrefix >/dev/null ||
git config --local format.subjectPrefix "PATCH libdrm" 2>/dev/null
-git config --local --get sendemail.to ||
+git config --local --get sendemail.to >/dev/null ||
git config --local sendemail.to "dri-devel@lists.freedesktop.org" 2>/dev/null
+autoreconf --force --verbose --install || exit 1
+cd "$ORIGDIR" || exit $?
+
if test -z "$NOCONFIGURE"; then
"$srcdir"/configure "$@"
fi
diff --git a/configure.ac b/configure.ac
index 1da9d86b..7e7c8d38 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
AC_PREREQ([2.63])
AC_INIT([libdrm],
- [2.4.75],
+ [2.4.97],
[https://bugs.freedesktop.org/enter_bug.cgi?product=DRI],
[libdrm])
@@ -28,6 +28,7 @@ AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
+PKG_PROG_PKG_CONFIG
# Require xorg-macros minimum of 1.12 for XORG_WITH_XSLTPROC
m4_ifndef([XORG_MACROS_VERSION],
@@ -44,6 +45,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# Check for programs
AC_PROG_CC
AC_PROG_CC_C99
+AC_PROG_NM
if test "x$ac_cv_prog_cc_c99" = xno; then
AC_MSG_ERROR([Building libdrm requires C99 enabled compiler])
@@ -53,20 +55,39 @@ AC_USE_SYSTEM_EXTENSIONS
AC_SYS_LARGEFILE
AC_FUNC_ALLOCA
+save_CFLAGS="$CFLAGS"
+export CFLAGS="$CFLAGS -Werror"
AC_HEADER_MAJOR
+CFLAGS="$save_CFLAGS"
+
AC_CHECK_HEADERS([sys/sysctl.h sys/select.h])
# Initialize libtool
LT_PREREQ([2.2])
LT_INIT([disable-static])
-
-
-AC_SUBST(PTHREADSTUBS_CFLAGS)
-AC_SUBST(PTHREADSTUBS_LIBS)
+dnl pthread-stubs is mandatory on some BSD platforms, due to the nature of the
+dnl project. Even then there's a notable issue as described in the project README
+case "$host_os" in
+linux* | cygwin* | darwin* | solaris* | *-gnu* | gnu* | openbsd*)
+ pthread_stubs_possible="no"
+ ;;
+* )
+ pthread_stubs_possible="yes"
+ ;;
+esac
+
+if test "x$pthread_stubs_possible" = xyes; then
+ PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs >= 0.4)
+ AC_SUBST(PTHREADSTUBS_CFLAGS)
+ AC_SUBST(PTHREADSTUBS_LIBS)
+fi
pkgconfigdir=${libdir}/pkgconfig
AC_SUBST(pkgconfigdir)
+libdrmdatadir=${datadir}/libdrm
+AC_SUBST(libdrmdatadir)
+
AC_ARG_ENABLE([udev],
[AS_HELP_STRING([--enable-udev],
[Enable support for using udev instead of mknod (default: disabled)])],
@@ -127,11 +148,6 @@ AC_ARG_ENABLE(tegra-experimental-api,
[Enable support for Tegra's experimental API (default: disabled)]),
[TEGRA=$enableval], [TEGRA=no])
-AC_ARG_ENABLE(rockchip-experimental-api,
- AS_HELP_STRING([--enable-rockchip-experimental-api],
- [Enable support for rockchip's experimental API (default: disabled)]),
- [ROCKCHIP=$enableval], [ROCKCHIP=no])
-
AC_ARG_ENABLE(vc4,
AS_HELP_STRING([--disable-vc4],
[Enable support for vc4's API (default: auto, enabled on arm)]),
@@ -173,7 +189,9 @@ AC_CHECK_FUNCS([clock_gettime], [CLOCK_LIB=],
[AC_MSG_ERROR([Couldn't find clock_gettime])])])
AC_SUBST([CLOCK_LIB])
-AC_CHECK_FUNCS([open_memstream], [HAVE_OPEN_MEMSTREAM=yes])
+AC_CHECK_FUNCS([open_memstream],
+ [AC_DEFINE([HAVE_OPEN_MEMSTREAM], 1, [Have open_memstream()])],
+ [AC_DEFINE([HAVE_OPEN_MEMSTREAM], 0)])
dnl Use lots of warning flags with with gcc and compatible compilers
@@ -182,7 +200,7 @@ dnl skipped and all flags rechecked. So there's no need to do anything
dnl else. If for any reason you need to force a recheck, just change
dnl MAYBE_WARN in an ignorable way (like adding whitespace)
-MAYBE_WARN="-Wall -Wextra \
+MAYBE_WARN="-Wall -Wextra -Werror=undef \
-Wsign-compare -Werror-implicit-function-declaration \
-Wpointer-arith -Wwrite-strings -Wstrict-prototypes \
-Wmissing-prototypes -Wmissing-declarations -Wnested-externs \
@@ -244,9 +262,13 @@ AC_CACHE_CHECK([for native atomic primitives], drm_cv_atomic_primitives, [
if test "x$drm_cv_atomic_primitives" = xIntel; then
AC_DEFINE(HAVE_LIBDRM_ATOMIC_PRIMITIVES, 1,
[Enable if your compiler supports the Intel __sync_* atomic primitives])
+else
+ AC_DEFINE(HAVE_LIBDRM_ATOMIC_PRIMITIVES, 0)
fi
if test "x$drm_cv_atomic_primitives" = "xlibatomic-ops"; then
AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 1, [Enable if you have libatomic-ops-dev installed])
+else
+ AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 0)
fi
dnl Print out the approapriate message considering the value set be the
@@ -325,6 +347,8 @@ AC_SUBST(PCIACCESS_LIBS)
if test "x$UDEV" = xyes; then
AC_DEFINE(UDEV, 1, [Have UDEV support])
+else
+ AC_DEFINE(UDEV, 0)
fi
AC_CANONICAL_HOST
@@ -343,32 +367,34 @@ AM_CONDITIONAL(HAVE_LIBKMS, [test "x$LIBKMS" = xyes])
AM_CONDITIONAL(HAVE_INTEL, [test "x$INTEL" = xyes])
if test "x$INTEL" = xyes; then
AC_DEFINE(HAVE_INTEL, 1, [Have intel support])
+else
+ AC_DEFINE(HAVE_INTEL, 0)
fi
AM_CONDITIONAL(HAVE_VMWGFX, [test "x$VMWGFX" = xyes])
if test "x$VMWGFX" = xyes; then
AC_DEFINE(HAVE_VMWGFX, 1, [Have vmwgfx kernel headers])
+else
+ AC_DEFINE(HAVE_VMWGFX, 0)
fi
AM_CONDITIONAL(HAVE_NOUVEAU, [test "x$NOUVEAU" = xyes])
if test "x$NOUVEAU" = xyes; then
AC_DEFINE(HAVE_NOUVEAU, 1, [Have nouveau (nvidia) support])
+else
+ AC_DEFINE(HAVE_NOUVEAU, 0)
fi
AM_CONDITIONAL(HAVE_OMAP, [test "x$OMAP" = xyes])
-if test "x$OMAP" = xyes; then
- AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support])
-fi
AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes])
if test "x$EXYNOS" = xyes; then
AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
+else
+ AC_DEFINE(HAVE_EXYNOS, 0)
fi
AM_CONDITIONAL(HAVE_FREEDRENO, [test "x$FREEDRENO" = xyes])
-if test "x$FREEDRENO" = xyes; then
- AC_DEFINE(HAVE_FREEDRENO, 1, [Have freedreno support])
-fi
if test "x$FREEDRENO_KGSL" = xyes; then
if test "x$FREEDRENO" != xyes; then
@@ -378,11 +404,15 @@ fi
AM_CONDITIONAL(HAVE_FREEDRENO_KGSL, [test "x$FREEDRENO_KGSL" = xyes])
if test "x$FREEDRENO_KGSL" = xyes; then
AC_DEFINE(HAVE_FREEDRENO_KGSL, 1, [Have freedreno support for KGSL kernel interface])
+else
+ AC_DEFINE(HAVE_FREEDRENO_KGSL, 0)
fi
AM_CONDITIONAL(HAVE_RADEON, [test "x$RADEON" = xyes])
if test "x$RADEON" = xyes; then
AC_DEFINE(HAVE_RADEON, 1, [Have radeon support])
+else
+ AC_DEFINE(HAVE_RADEON, 0)
fi
if test "x$AMDGPU" != xno; then
@@ -409,36 +439,25 @@ AM_CONDITIONAL(HAVE_AMDGPU, [test "x$AMDGPU" = xyes])
if test "x$AMDGPU" = xyes; then
AC_DEFINE(HAVE_AMDGPU, 1, [Have amdgpu support])
- AC_DEFINE(HAVE_CUNIT, [test "x$have_cunit" != "xno"], [Enable CUNIT Have amdgpu support])
-
if test "x$have_cunit" = "xno"; then
AC_MSG_WARN([Could not find cunit library. Disabling amdgpu tests])
fi
+else
+ AC_DEFINE(HAVE_AMDGPU, 0)
fi
AM_CONDITIONAL(HAVE_TEGRA, [test "x$TEGRA" = xyes])
-if test "x$TEGRA" = xyes; then
- AC_DEFINE(HAVE_TEGRA, 1, [Have Tegra support])
-fi
-
-AM_CONDITIONAL(HAVE_ROCKCHIP, [test "x$ROCKCHIP" = xyes])
-if test "x$ROCKCHIP" = xyes; then
- AC_DEFINE(HAVE_ROCKCHIP, 1, [Have ROCKCHIP support])
AM_CONDITIONAL(HAVE_VC4, [test "x$VC4" = xyes])
if test "x$VC4" = xyes; then
AC_DEFINE(HAVE_VC4, 1, [Have VC4 support])
+else
+ AC_DEFINE(HAVE_VC4, 0)
fi
AM_CONDITIONAL(HAVE_ETNAVIV, [test "x$ETNAVIV" = xyes])
-if test "x$ETNAVIV" = xyes; then
- AC_DEFINE(HAVE_ETNAVIV, 1, [Have etnaviv support])
-fi
AM_CONDITIONAL(HAVE_INSTALL_TESTS, [test "x$INSTALL_TESTS" = xyes])
-if test "x$INSTALL_TESTS" = xyes; then
- AC_DEFINE(HAVE_INSTALL_TESTS, 1, [Install test programs])
-fi
AC_ARG_ENABLE([cairo-tests],
[AS_HELP_STRING([--enable-cairo-tests],
@@ -456,6 +475,8 @@ if test "x$CAIRO" = xyes; then
AC_MSG_ERROR([Cairo support required but not present])
fi
AC_DEFINE(HAVE_CAIRO, 1, [Have Cairo support])
+else
+ AC_DEFINE(HAVE_CAIRO, 0)
fi
AC_MSG_RESULT([$CAIRO])
AM_CONDITIONAL(HAVE_CAIRO, [test "x$CAIRO" = xyes])
@@ -497,6 +518,8 @@ if test "x$VALGRIND" = "xyes"; then
AC_MSG_ERROR([Valgrind support required but not present])
fi
AC_DEFINE([HAVE_VALGRIND], 1, [Use valgrind intrinsics to suppress false warnings])
+else
+ AC_DEFINE([HAVE_VALGRIND], 0)
fi
AC_MSG_RESULT([$VALGRIND])
@@ -514,11 +537,16 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
if test "x$HAVE_ATTRIBUTE_VISIBILITY" = xyes; then
AC_DEFINE(HAVE_VISIBILITY, 1, [Compiler supports __attribute__(("hidden"))])
+else
+ AC_DEFINE(HAVE_VISIBILITY, 0)
fi
+CFLAGS="$CFLAGS -include config.h"
+
AC_SUBST(WARN_CFLAGS)
AC_CONFIG_FILES([
Makefile
+ data/Makefile
libkms/Makefile
libkms/libkms.pc
intel/Makefile
@@ -537,8 +565,6 @@ AC_CONFIG_FILES([
freedreno/libdrm_freedreno.pc
tegra/Makefile
tegra/libdrm_tegra.pc
- rockchip/Makefile
- rockchip/libdrm_rockchip.pc
vc4/Makefile
vc4/libdrm_vc4.pc
etnaviv/Makefile
@@ -555,7 +581,6 @@ AC_CONFIG_FILES([
tests/exynos/Makefile
tests/tegra/Makefile
tests/nouveau/Makefile
- tests/planetest/Makefile
tests/etnaviv/Makefile
tests/util/Makefile
man/Makefile
@@ -575,7 +600,6 @@ echo " OMAP API $OMAP"
echo " EXYNOS API $EXYNOS"
echo " Freedreno API $FREEDRENO (kgsl: $FREEDRENO_KGSL)"
echo " Tegra API $TEGRA"
-echo " Rockchip API $ROCKCHIP"
echo " VC4 API $VC4"
echo " Etnaviv API $ETNAVIV"
echo ""
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644
index 00000000..897a7f35
--- /dev/null
+++ b/data/Makefile.am
@@ -0,0 +1,25 @@
+# Copyright © 2017 Advanced Micro Devices, Inc.
+# 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
+# on 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
+# ADAM JACKSON 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.
+
+libdrmdatadir = @libdrmdatadir@
+if HAVE_AMDGPU
+dist_libdrmdata_DATA = amdgpu.ids
+endif
diff --git a/data/amdgpu.ids b/data/amdgpu.ids
new file mode 100644
index 00000000..d9ed5660
--- /dev/null
+++ b/data/amdgpu.ids
@@ -0,0 +1,197 @@
+# List of AMDGPU IDs
+#
+# Syntax:
+# device_id, revision_id, product_name <-- single tab after comma
+
+1.0.0
+6600, 0, AMD Radeon HD 8600/8700M
+6600, 81, AMD Radeon (TM) R7 M370
+6601, 0, AMD Radeon (TM) HD 8500M/8700M
+6604, 0, AMD Radeon R7 M265 Series
+6604, 81, AMD Radeon (TM) R7 M350
+6605, 0, AMD Radeon R7 M260 Series
+6605, 81, AMD Radeon (TM) R7 M340
+6606, 0, AMD Radeon HD 8790M
+6607, 0, AMD Radeon (TM) HD8530M
+6608, 0, AMD FirePro W2100
+6610, 0, AMD Radeon HD 8600 Series
+6610, 81, AMD Radeon (TM) R7 350
+6610, 83, AMD Radeon (TM) R5 340
+6611, 0, AMD Radeon HD 8500 Series
+6613, 0, AMD Radeon HD 8500 series
+6617, C7, AMD Radeon R7 240 Series
+6640, 0, AMD Radeon HD 8950
+6640, 80, AMD Radeon (TM) R9 M380
+6646, 0, AMD Radeon R9 M280X
+6646, 80, AMD Radeon (TM) R9 M470X
+6647, 0, AMD Radeon R9 M270X
+6647, 80, AMD Radeon (TM) R9 M380
+6649, 0, AMD FirePro W5100
+6658, 0, AMD Radeon R7 200 Series
+665C, 0, AMD Radeon HD 7700 Series
+665D, 0, AMD Radeon R7 200 Series
+665F, 81, AMD Radeon (TM) R7 300 Series
+6660, 0, AMD Radeon HD 8600M Series
+6660, 81, AMD Radeon (TM) R5 M335
+6660, 83, AMD Radeon (TM) R5 M330
+6663, 0, AMD Radeon HD 8500M Series
+6663, 83, AMD Radeon (TM) R5 M320
+6664, 0, AMD Radeon R5 M200 Series
+6665, 0, AMD Radeon R5 M200 Series
+6665, 83, AMD Radeon (TM) R5 M320
+6667, 0, AMD Radeon R5 M200 Series
+666F, 0, AMD Radeon HD 8500M
+6780, 0, ATI FirePro V (FireGL V) Graphics Adapter
+678A, 0, ATI FirePro V (FireGL V) Graphics Adapter
+6798, 0, AMD Radeon HD 7900 Series
+679A, 0, AMD Radeon HD 7900 Series
+679B, 0, AMD Radeon HD 7900 Series
+679E, 0, AMD Radeon HD 7800 Series
+67A0, 0, AMD Radeon FirePro W9100
+67A1, 0, AMD Radeon FirePro W8100
+67B0, 0, AMD Radeon R9 200 Series
+67B0, 80, AMD Radeon (TM) R9 390 Series
+67B1, 0, AMD Radeon R9 200 Series
+67B1, 80, AMD Radeon (TM) R9 390 Series
+67B9, 0, AMD Radeon R9 200 Series
+67DF, C1, Radeon RX 580 Series
+67DF, C2, Radeon RX 570 Series
+67DF, C3, Radeon RX 580 Series
+67DF, C4, AMD Radeon (TM) RX 480 Graphics
+67DF, C5, AMD Radeon (TM) RX 470 Graphics
+67DF, C6, Radeon RX 570 Series
+67DF, C7, AMD Radeon (TM) RX 480 Graphics
+67DF, CF, AMD Radeon (TM) RX 470 Graphics
+67DF, D7, Radeon(TM) RX 470 Graphics
+67DF, E0, Radeon RX 470 Series
+67DF, E1, Radeon RX 590 Series
+67DF, E3, Radeon RX Series
+67DF, E7, Radeon RX 580 Series
+67DF, EF, Radeon RX 570 Series
+67DF, F7, Radeon RX P30PH
+67C2, 01, AMD Radeon (TM) Pro V7350x2
+67C2, 02, AMD Radeon (TM) Pro V7300X
+67C4, 00, AMD Radeon (TM) Pro WX 7100 Graphics
+67C7, 00, AMD Radeon (TM) Pro WX 5100 Graphics
+67C0, 00, AMD Radeon (TM) Pro WX 7100 Graphics
+67D0, 01, AMD Radeon (TM) Pro V7350x2
+67D0, 02, AMD Radeon (TM) Pro V7300X
+67E0, 00, AMD Radeon (TM) Pro WX Series
+67E3, 00, AMD Radeon (TM) Pro WX 4100
+67E8, 00, AMD Radeon (TM) Pro WX Series
+67E8, 01, AMD Radeon (TM) Pro WX Series
+67E8, 80, AMD Radeon (TM) E9260 Graphics
+67EB, 00, AMD Radeon (TM) Pro V5300X
+67EF, C0, AMD Radeon (TM) RX Graphics
+67EF, C1, AMD Radeon (TM) RX 460 Graphics
+67EF, C3, Radeon RX Series
+67EF, C5, AMD Radeon (TM) RX 460 Graphics
+67EF, C7, AMD Radeon (TM) RX Graphics
+67EF, CF, AMD Radeon (TM) RX 460 Graphics
+67EF, E2, RX 560X
+67EF, E0, Radeon RX 560 Series
+67EF, E1, Radeon RX Series
+67EF, E3, Radeon RX Series
+67EF, E5, Radeon RX 560 Series
+67EF, EF, AMD Radeon (TM) RX Graphics
+67EF, FF, Radeon(TM) RX 460 Graphics
+67FF, C0, AMD Radeon (TM) RX Graphics
+67FF, C1, AMD Radeon (TM) RX Graphics
+67FF, CF, Radeon RX 560 Series
+67FF, EF, Radeon RX 560 Series
+67FF, FF, Radeon RX 550 Series
+6800, 0, AMD Radeon HD 7970M
+6801, 0, AMD Radeon(TM) HD8970M
+6808, 0, ATI FirePro V(FireGL V) Graphics Adapter
+6809, 0, ATI FirePro V(FireGL V) Graphics Adapter
+6810, 0, AMD Radeon(TM) HD 8800 Series
+6810, 81, AMD Radeon (TM) R7 370 Series
+6811, 0, AMD Radeon(TM) HD8800 Series
+6811, 81, AMD Radeon (TM) R7 300 Series
+6818, 0, AMD Radeon HD 7800 Series
+6819, 0, AMD Radeon HD 7800 Series
+6820, 0, AMD Radeon HD 8800M Series
+6820, 81, AMD Radeon (TM) R9 M375
+6820, 83, AMD Radeon (TM) R9 M375X
+6821, 0, AMD Radeon HD 8800M Series
+6821, 87, AMD Radeon (TM) R7 M380
+6821, 83, AMD Radeon R9 (TM) M370X
+6822, 0, AMD Radeon E8860
+6823, 0, AMD Radeon HD 8800M Series
+6825, 0, AMD Radeon HD 7800M Series
+6827, 0, AMD Radeon HD 7800M Series
+6828, 0, ATI FirePro V(FireGL V) Graphics Adapter
+682B, 0, AMD Radeon HD 8800M Series
+682B, 87, AMD Radeon (TM) R9 M360
+682C, 0, AMD FirePro W4100
+682D, 0, AMD Radeon HD 7700M Series
+682F, 0, AMD Radeon HD 7700M Series
+6835, 0, AMD Radeon R7 Series / HD 9000 Series
+6837, 0, AMD Radeon HD7700 Series
+683D, 0, AMD Radeon HD 7700 Series
+683F, 0, AMD Radeon HD 7700 Series
+6860, 00, Radeon Instinct MI25
+6860, 01, Radeon Instinct MI25
+6860, 02, Radeon Instinct MI25
+6860, 03, Radeon Pro V340
+6860, 04, Radeon Instinct MI25x2
+6861, 00, Radeon Pro WX 9100
+6862, 00, Radeon Pro SSG
+6863, 00, Radeon Vega Frontier Edition
+6864, 03, Radeon Pro V340
+6864, 04, Instinct MI25x2
+6868, 00, Radeon (TM) PRO WX 8200
+686C, 00, Radeon Instinct MI25 MxGPU
+686C, 01, Radeon Instinct MI25 MxGPU
+686C, 02, Radeon Instinct MI25 MxGPU
+686C, 03, Radeon Pro V340 MxGPU
+686C, 04, Radeon Instinct MI25x2 MxGPU
+686C, 05, Radeon Pro V340L MxGPU
+686C, 06, Radeon Instinct MI25 MxGPU
+687F, C0, Radeon RX Vega
+687F, C1, Radeon RX Vega
+687F, C3, Radeon RX Vega
+6900, 0, AMD Radeon R7 M260
+6900, 81, AMD Radeon (TM) R7 M360
+6900, 83, AMD Radeon (TM) R7 M340
+6901, 0, AMD Radeon R5 M255
+6907, 0, AMD Radeon R5 M255
+6907, 87, AMD Radeon (TM) R5 M315
+6920, 0, AMD RADEON R9 M395X
+6920, 1, AMD RADEON R9 M390X
+6921, 0, AMD Radeon R9 M295X
+6929, 0, AMD FirePro S7150
+692B, 0, AMD FirePro W7100
+6938, 0, AMD Radeon R9 200 Series
+6938, F0, AMD Radeon R9 200 Series
+6938, F1, AMD Radeon (TM) R9 380 Series
+6939, F0, AMD Radeon R9 200 Series
+6939, 0, AMD Radeon R9 200 Series
+6939, F1, AMD Radeon (TM) R9 380 Series
+6980, 00, Radeon Pro WX3100
+6985, 00, AMD Radeon Pro WX3100
+6987, 80, AMD Embedded Radeon E9171
+6987, C0, Radeon 550X Series
+6987, C3, Radeon 540X Series
+6995, 00, AMD Radeon Pro WX2100
+6997, 00, Radeon Pro WX2100
+699F, 81, AMD Embedded Radeon E9170 Series
+699F, C0, Radeon 500 Series
+699F, C1, Radeon 540 Series
+699F, C3, Radeon 500 Series
+699F, C7, Radeon 550 Series
+7300, C1, AMD FirePro (TM) S9300 x2
+7300, C8, AMD Radeon (TM) R9 Fury Series
+7300, C9, Radeon (TM) Pro Duo
+7300, CB, AMD Radeon (TM) R9 Fury Series
+7300, CA, AMD Radeon (TM) R9 Fury Series
+9874, C4, AMD Radeon R7 Graphics
+9874, C5, AMD Radeon R6 Graphics
+9874, C6, AMD Radeon R6 Graphics
+9874, C7, AMD Radeon R5 Graphics
+9874, C8, AMD Radeon R7 Graphics
+9874, 81, AMD Radeon R6 Graphics
+9874, 87, AMD Radeon R5 Graphics
+9874, 85, AMD Radeon R6 Graphics
+9874, 84, AMD Radeon R7 Graphics
+6FDF, EF, AMD Radeon RX 580 2048SP
diff --git a/data/meson.build b/data/meson.build
new file mode 100644
index 00000000..9c26b66e
--- /dev/null
+++ b/data/meson.build
@@ -0,0 +1,27 @@
+# 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.
+
+if with_amdgpu
+ install_data(
+ 'amdgpu.ids',
+ install_mode : 'rw-r--r--',
+ install_dir : datadir_amdgpu,
+ )
+endif
diff --git a/etnaviv/Makefile.am b/etnaviv/Makefile.am
index be96ba86..648e3c5b 100644
--- a/etnaviv/Makefile.am
+++ b/etnaviv/Makefile.am
@@ -2,6 +2,7 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
@@ -22,5 +23,6 @@ libdrm_etnavivinclude_HEADERS = $(LIBDRM_ETNAVIV_H_FILES)
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_etnaviv.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = etnaviv-symbol-check
EXTRA_DIST = $(TESTS)
diff --git a/etnaviv/Makefile.sources b/etnaviv/Makefile.sources
index 52580567..0eb73783 100644
--- a/etnaviv/Makefile.sources
+++ b/etnaviv/Makefile.sources
@@ -3,6 +3,7 @@ LIBDRM_ETNAVIV_FILES := \
etnaviv_gpu.c \
etnaviv_bo.c \
etnaviv_bo_cache.c \
+ etnaviv_perfmon.c \
etnaviv_pipe.c \
etnaviv_cmd_stream.c \
etnaviv_drm.h \
diff --git a/etnaviv/etnaviv-symbol-check b/etnaviv/etnaviv-symbol-check
index 22afd168..18910688 100755
--- a/etnaviv/etnaviv-symbol-check
+++ b/etnaviv/etnaviv-symbol-check
@@ -1,5 +1,7 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.sources/LIBDRM_ETNAVIV_H_FILES
@@ -39,8 +41,14 @@ etna_cmd_stream_new
etna_cmd_stream_del
etna_cmd_stream_timestamp
etna_cmd_stream_flush
+etna_cmd_stream_flush2
etna_cmd_stream_finish
+etna_cmd_stream_perf
etna_cmd_stream_reloc
+etna_perfmon_create
+etna_perfmon_del
+etna_perfmon_get_dom_by_name
+etna_perfmon_get_sig_by_name
EOF
done)
diff --git a/etnaviv/etnaviv_bo.c b/etnaviv/etnaviv_bo.c
index 4ad0434e..43ce6b4e 100644
--- a/etnaviv/etnaviv_bo.c
+++ b/etnaviv/etnaviv_bo.c
@@ -24,10 +24,6 @@
* Christian Gmeiner <christian.gmeiner@gmail.com>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "etnaviv_priv.h"
#include "etnaviv_drmif.h"
@@ -108,7 +104,7 @@ static struct etna_bo *bo_from_handle(struct etna_device *dev,
}
/* allocate a new (un-tiled) buffer object */
-struct etna_bo *etna_bo_new(struct etna_device *dev, uint32_t size,
+drm_public struct etna_bo *etna_bo_new(struct etna_device *dev, uint32_t size,
uint32_t flags)
{
struct etna_bo *bo;
@@ -135,7 +131,7 @@ struct etna_bo *etna_bo_new(struct etna_device *dev, uint32_t size,
return bo;
}
-struct etna_bo *etna_bo_ref(struct etna_bo *bo)
+drm_public struct etna_bo *etna_bo_ref(struct etna_bo *bo)
{
atomic_inc(&bo->refcnt);
@@ -163,7 +159,8 @@ static int get_buffer_info(struct etna_bo *bo)
}
/* import a buffer object from DRI2 name */
-struct etna_bo *etna_bo_from_name(struct etna_device *dev, uint32_t name)
+drm_public struct etna_bo *etna_bo_from_name(struct etna_device *dev,
+ uint32_t name)
{
struct etna_bo *bo;
struct drm_gem_open req = {
@@ -173,7 +170,7 @@ struct etna_bo *etna_bo_from_name(struct etna_device *dev, uint32_t name)
pthread_mutex_lock(&table_lock);
/* check name table first, to see if bo is already open: */
- bo = lookup_bo(dev->name_table, req.handle);
+ bo = lookup_bo(dev->name_table, name);
if (bo)
goto out_unlock;
@@ -200,16 +197,21 @@ out_unlock:
* fd so caller should close() the fd when it is otherwise done
* with it (even if it is still using the 'struct etna_bo *')
*/
-struct etna_bo *etna_bo_from_dmabuf(struct etna_device *dev, int fd)
+drm_public struct etna_bo *etna_bo_from_dmabuf(struct etna_device *dev, int fd)
{
struct etna_bo *bo;
int ret, size;
uint32_t handle;
+ /* take the lock before calling drmPrimeFDToHandle to avoid
+ * racing against etna_bo_del, which might invalidate the
+ * returned handle.
+ */
pthread_mutex_lock(&table_lock);
ret = drmPrimeFDToHandle(dev->fd, fd, &handle);
if (ret) {
+ pthread_mutex_unlock(&table_lock);
return NULL;
}
@@ -230,7 +232,7 @@ out_unlock:
}
/* destroy a buffer object */
-void etna_bo_del(struct etna_bo *bo)
+drm_public void etna_bo_del(struct etna_bo *bo)
{
struct etna_device *dev = bo->dev;
@@ -252,7 +254,7 @@ out:
}
/* get the global flink/DRI2 buffer name */
-int etna_bo_get_name(struct etna_bo *bo, uint32_t *name)
+drm_public int etna_bo_get_name(struct etna_bo *bo, uint32_t *name)
{
if (!bo->name) {
struct drm_gem_flink req = {
@@ -276,7 +278,7 @@ int etna_bo_get_name(struct etna_bo *bo, uint32_t *name)
return 0;
}
-uint32_t etna_bo_handle(struct etna_bo *bo)
+drm_public uint32_t etna_bo_handle(struct etna_bo *bo)
{
return bo->handle;
}
@@ -284,7 +286,7 @@ uint32_t etna_bo_handle(struct etna_bo *bo)
/* caller owns the dmabuf fd that is returned and is responsible
* to close() it when done
*/
-int etna_bo_dmabuf(struct etna_bo *bo)
+drm_public int etna_bo_dmabuf(struct etna_bo *bo)
{
int ret, prime_fd;
@@ -300,12 +302,12 @@ int etna_bo_dmabuf(struct etna_bo *bo)
return prime_fd;
}
-uint32_t etna_bo_size(struct etna_bo *bo)
+drm_public uint32_t etna_bo_size(struct etna_bo *bo)
{
return bo->size;
}
-void *etna_bo_map(struct etna_bo *bo)
+drm_public void *etna_bo_map(struct etna_bo *bo)
{
if (!bo->map) {
if (!bo->offset) {
@@ -323,7 +325,7 @@ void *etna_bo_map(struct etna_bo *bo)
return bo->map;
}
-int etna_bo_cpu_prep(struct etna_bo *bo, uint32_t op)
+drm_public int etna_bo_cpu_prep(struct etna_bo *bo, uint32_t op)
{
struct drm_etnaviv_gem_cpu_prep req = {
.handle = bo->handle,
@@ -336,7 +338,7 @@ int etna_bo_cpu_prep(struct etna_bo *bo, uint32_t op)
&req, sizeof(req));
}
-void etna_bo_cpu_fini(struct etna_bo *bo)
+drm_public void etna_bo_cpu_fini(struct etna_bo *bo)
{
struct drm_etnaviv_gem_cpu_fini req = {
.handle = bo->handle,
diff --git a/etnaviv/etnaviv_bo_cache.c b/etnaviv/etnaviv_bo_cache.c
index 8924651f..c81de262 100644
--- a/etnaviv/etnaviv_bo_cache.c
+++ b/etnaviv/etnaviv_bo_cache.c
@@ -24,10 +24,6 @@
* Christian Gmeiner <christian.gmeiner@gmail.com>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "etnaviv_priv.h"
#include "etnaviv_drmif.h"
@@ -124,20 +120,32 @@ static int is_idle(struct etna_bo *bo)
static struct etna_bo *find_in_bucket(struct etna_bo_bucket *bucket, uint32_t flags)
{
- struct etna_bo *bo = NULL;
+ struct etna_bo *bo = NULL, *tmp;
pthread_mutex_lock(&table_lock);
- while (!LIST_IS_EMPTY(&bucket->list)) {
- bo = LIST_ENTRY(struct etna_bo, bucket->list.next, list);
- if (bo->flags == flags && is_idle(bo)) {
- list_del(&bo->list);
- break;
+ if (LIST_IS_EMPTY(&bucket->list))
+ goto out_unlock;
+
+ LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bucket->list, list) {
+ /* skip BOs with different flags */
+ if (bo->flags != flags)
+ continue;
+
+ /* check if the first BO with matching flags is idle */
+ if (is_idle(bo)) {
+ list_delinit(&bo->list);
+ goto out_unlock;
}
- bo = NULL;
+ /* If the oldest BO is still busy, don't try younger ones */
break;
}
+
+ /* There was no matching buffer found */
+ bo = NULL;
+
+out_unlock:
pthread_mutex_unlock(&table_lock);
return bo;
diff --git a/etnaviv/etnaviv_cmd_stream.c b/etnaviv/etnaviv_cmd_stream.c
index 9ce3f363..7139c324 100644
--- a/etnaviv/etnaviv_cmd_stream.c
+++ b/etnaviv/etnaviv_cmd_stream.c
@@ -24,10 +24,6 @@
* Christian Gmeiner <christian.gmeiner@gmail.com>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <assert.h>
#include "etnaviv_drmif.h"
@@ -59,7 +55,8 @@ etna_cmd_stream_priv(struct etna_cmd_stream *stream)
return (struct etna_cmd_stream_priv *)stream;
}
-struct etna_cmd_stream *etna_cmd_stream_new(struct etna_pipe *pipe, uint32_t size,
+drm_public struct etna_cmd_stream *etna_cmd_stream_new(struct etna_pipe *pipe,
+ uint32_t size,
void (*reset_notify)(struct etna_cmd_stream *stream, void *priv),
void *priv)
{
@@ -99,12 +96,13 @@ fail:
return NULL;
}
-void etna_cmd_stream_del(struct etna_cmd_stream *stream)
+drm_public void etna_cmd_stream_del(struct etna_cmd_stream *stream)
{
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
free(stream->buffer);
free(priv->submit.relocs);
+ free(priv->submit.pmrs);
free(priv);
}
@@ -115,13 +113,14 @@ static void reset_buffer(struct etna_cmd_stream *stream)
stream->offset = 0;
priv->submit.nr_bos = 0;
priv->submit.nr_relocs = 0;
+ priv->submit.nr_pmrs = 0;
priv->nr_bos = 0;
if (priv->reset_notify)
priv->reset_notify(stream, priv->reset_notify_priv);
}
-uint32_t etna_cmd_stream_timestamp(struct etna_cmd_stream *stream)
+drm_public uint32_t etna_cmd_stream_timestamp(struct etna_cmd_stream *stream)
{
return etna_cmd_stream_priv(stream)->last_timestamp;
}
@@ -177,7 +176,8 @@ static uint32_t bo2idx(struct etna_cmd_stream *stream, struct etna_bo *bo,
return idx;
}
-static void flush(struct etna_cmd_stream *stream)
+static void flush(struct etna_cmd_stream *stream, int in_fence_fd,
+ int *out_fence_fd)
{
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
int ret, id = priv->pipe->id;
@@ -190,10 +190,20 @@ static void flush(struct etna_cmd_stream *stream)
.nr_bos = priv->submit.nr_bos,
.relocs = VOID2U64(priv->submit.relocs),
.nr_relocs = priv->submit.nr_relocs,
+ .pmrs = VOID2U64(priv->submit.pmrs),
+ .nr_pmrs = priv->submit.nr_pmrs,
.stream = VOID2U64(stream->buffer),
.stream_size = stream->offset * 4, /* in bytes */
};
+ if (in_fence_fd != -1) {
+ req.flags |= ETNA_SUBMIT_FENCE_FD_IN | ETNA_SUBMIT_NO_IMPLICIT;
+ req.fence_fd = in_fence_fd;
+ }
+
+ if (out_fence_fd)
+ req.flags |= ETNA_SUBMIT_FENCE_FD_OUT;
+
ret = drmCommandWriteRead(gpu->dev->fd, DRM_ETNAVIV_GEM_SUBMIT,
&req, sizeof(req));
@@ -208,24 +218,36 @@ static void flush(struct etna_cmd_stream *stream)
bo->current_stream = NULL;
etna_bo_del(bo);
}
+
+ if (out_fence_fd)
+ *out_fence_fd = req.fence_fd;
}
-void etna_cmd_stream_flush(struct etna_cmd_stream *stream)
+drm_public void etna_cmd_stream_flush(struct etna_cmd_stream *stream)
{
- flush(stream);
+ flush(stream, -1, NULL);
reset_buffer(stream);
}
-void etna_cmd_stream_finish(struct etna_cmd_stream *stream)
+drm_public void etna_cmd_stream_flush2(struct etna_cmd_stream *stream,
+ int in_fence_fd,
+ int *out_fence_fd)
+{
+ flush(stream, in_fence_fd, out_fence_fd);
+ reset_buffer(stream);
+}
+
+drm_public void etna_cmd_stream_finish(struct etna_cmd_stream *stream)
{
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
- flush(stream);
+ flush(stream, -1, NULL);
etna_pipe_wait(priv->pipe, priv->last_timestamp, 5000);
reset_buffer(stream);
}
-void etna_cmd_stream_reloc(struct etna_cmd_stream *stream, const struct etna_reloc *r)
+drm_public void etna_cmd_stream_reloc(struct etna_cmd_stream *stream,
+ const struct etna_reloc *r)
{
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
struct drm_etnaviv_gem_submit_reloc *reloc;
@@ -241,3 +263,19 @@ void etna_cmd_stream_reloc(struct etna_cmd_stream *stream, const struct etna_rel
etna_cmd_stream_emit(stream, addr);
}
+
+drm_public void etna_cmd_stream_perf(struct etna_cmd_stream *stream, const struct etna_perf *p)
+{
+ struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
+ struct drm_etnaviv_gem_submit_pmr *pmr;
+ uint32_t idx = APPEND(&priv->submit, pmrs);
+
+ pmr = &priv->submit.pmrs[idx];
+
+ pmr->flags = p->flags;
+ pmr->sequence = p->sequence;
+ pmr->read_offset = p->offset;
+ pmr->read_idx = bo2idx(stream, p->bo, ETNA_SUBMIT_BO_READ | ETNA_SUBMIT_BO_WRITE);
+ pmr->domain = p->signal->domain->id;
+ pmr->signal = p->signal->signal;
+}
diff --git a/etnaviv/etnaviv_device.c b/etnaviv/etnaviv_device.c
index 3ce92030..699df256 100644
--- a/etnaviv/etnaviv_device.c
+++ b/etnaviv/etnaviv_device.c
@@ -24,10 +24,6 @@
* Christian Gmeiner <christian.gmeiner@gmail.com>
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <linux/stddef.h>
#include <linux/types.h>
@@ -45,7 +41,7 @@
static pthread_mutex_t table_lock = PTHREAD_MUTEX_INITIALIZER;
-struct etna_device *etna_device_new(int fd)
+drm_public struct etna_device *etna_device_new(int fd)
{
struct etna_device *dev = calloc(sizeof(*dev), 1);
@@ -63,7 +59,7 @@ struct etna_device *etna_device_new(int fd)
/* like etna_device_new() but creates it's own private dup() of the fd
* which is close()d when the device is finalized. */
-struct etna_device *etna_device_new_dup(int fd)
+drm_public struct etna_device *etna_device_new_dup(int fd)
{
int dup_fd = dup(fd);
struct etna_device *dev = etna_device_new(dup_fd);
@@ -76,7 +72,7 @@ struct etna_device *etna_device_new_dup(int fd)
return dev;
}
-struct etna_device *etna_device_ref(struct etna_device *dev)
+drm_public struct etna_device *etna_device_ref(struct etna_device *dev)
{
atomic_inc(&dev->refcnt);
@@ -103,7 +99,7 @@ drm_private void etna_device_del_locked(struct etna_device *dev)
etna_device_del_impl(dev);
}
-void etna_device_del(struct etna_device *dev)
+drm_public void etna_device_del(struct etna_device *dev)
{
if (!atomic_dec_and_test(&dev->refcnt))
return;
@@ -113,7 +109,7 @@ void etna_device_del(struct etna_device *dev)
pthread_mutex_unlock(&table_lock);
}
-int etna_device_fd(struct etna_device *dev)
+drm_public int etna_device_fd(struct etna_device *dev)
{
return dev->fd;
}
diff --git a/etnaviv/etnaviv_drm.h b/etnaviv/etnaviv_drm.h
index 2584c1cc..0d5c49dc 100644
--- a/etnaviv/etnaviv_drm.h
+++ b/etnaviv/etnaviv_drm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright (C) 2015 Etnaviv Project
*
@@ -54,6 +55,12 @@ struct drm_etnaviv_timespec {
#define ETNAVIV_PARAM_GPU_FEATURES_4 0x07
#define ETNAVIV_PARAM_GPU_FEATURES_5 0x08
#define ETNAVIV_PARAM_GPU_FEATURES_6 0x09
+#define ETNAVIV_PARAM_GPU_FEATURES_7 0x0a
+#define ETNAVIV_PARAM_GPU_FEATURES_8 0x0b
+#define ETNAVIV_PARAM_GPU_FEATURES_9 0x0c
+#define ETNAVIV_PARAM_GPU_FEATURES_10 0x0d
+#define ETNAVIV_PARAM_GPU_FEATURES_11 0x0e
+#define ETNAVIV_PARAM_GPU_FEATURES_12 0x0f
#define ETNAVIV_PARAM_GPU_STREAM_COUNT 0x10
#define ETNAVIV_PARAM_GPU_REGISTER_MAX 0x11
@@ -150,10 +157,29 @@ struct drm_etnaviv_gem_submit_bo {
__u64 presumed; /* in/out, presumed buffer address */
};
+/* performance monitor request (pmr) */
+#define ETNA_PM_PROCESS_PRE 0x0001
+#define ETNA_PM_PROCESS_POST 0x0002
+struct drm_etnaviv_gem_submit_pmr {
+ __u32 flags; /* in, when to process request (ETNA_PM_PROCESS_x) */
+ __u8 domain; /* in, pm domain */
+ __u8 pad;
+ __u16 signal; /* in, pm signal */
+ __u32 sequence; /* in, sequence number */
+ __u32 read_offset; /* in, offset from read_bo */
+ __u32 read_idx; /* in, index of read_bo buffer */
+};
+
/* Each cmdstream submit consists of a table of buffers involved, and
* one or more cmdstream buffers. This allows for conditional execution
* (context-restore), and IB buffers needed for per tile/bin draw cmds.
*/
+#define ETNA_SUBMIT_NO_IMPLICIT 0x0001
+#define ETNA_SUBMIT_FENCE_FD_IN 0x0002
+#define ETNA_SUBMIT_FENCE_FD_OUT 0x0004
+#define ETNA_SUBMIT_FLAGS (ETNA_SUBMIT_NO_IMPLICIT | \
+ ETNA_SUBMIT_FENCE_FD_IN | \
+ ETNA_SUBMIT_FENCE_FD_OUT)
#define ETNA_PIPE_3D 0x00
#define ETNA_PIPE_2D 0x01
#define ETNA_PIPE_VG 0x02
@@ -167,6 +193,11 @@ struct drm_etnaviv_gem_submit {
__u64 bos; /* in, ptr to array of submit_bo's */
__u64 relocs; /* in, ptr to array of submit_reloc's */
__u64 stream; /* in, ptr to cmdstream */
+ __u32 flags; /* in, mask of ETNA_SUBMIT_x */
+ __s32 fence_fd; /* in/out, fence fd (see ETNA_SUBMIT_FENCE_FD_x) */
+ __u64 pmrs; /* in, ptr to array of submit_pmr's */
+ __u32 nr_pmrs; /* in, number of submit_pmr's */
+ __u32 pad;
};
/* The normal way to synchronize with the GPU is just to CPU_PREP on
@@ -202,6 +233,27 @@ struct drm_etnaviv_gem_wait {
struct drm_etnaviv_timespec timeout; /* in */
};
+/*
+ * Performance Monitor (PM):
+ */
+
+struct drm_etnaviv_pm_domain {
+ __u32 pipe; /* in */
+ __u8 iter; /* in/out, select pm domain at index iter */
+ __u8 id; /* out, id of domain */
+ __u16 nr_signals; /* out, how many signals does this domain provide */
+ char name[64]; /* out, name of domain */
+};
+
+struct drm_etnaviv_pm_signal {
+ __u32 pipe; /* in */
+ __u8 domain; /* in, pm domain index */
+ __u8 pad;
+ __u16 iter; /* in/out, select pm source at index iter */
+ __u16 id; /* out, id of signal */
+ char name[64]; /* out, name of domain */
+};
+
#define DRM_ETNAVIV_GET_PARAM 0x00
/* placeholder:
#define DRM_ETNAVIV_SET_PARAM 0x01
@@ -214,7 +266,9 @@ struct drm_etnaviv_gem_wait {
#define DRM_ETNAVIV_WAIT_FENCE 0x07
#define DRM_ETNAVIV_GEM_USERPTR 0x08
#define DRM_ETNAVIV_GEM_WAIT 0x09
-#define DRM_ETNAVIV_NUM_IOCTLS 0x0a
+#define DRM_ETNAVIV_PM_QUERY_DOM 0x0a
+#define DRM_ETNAVIV_PM_QUERY_SIG 0x0b
+#define DRM_ETNAVIV_NUM_IOCTLS 0x0c
#define DRM_IOCTL_ETNAVIV_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GET_PARAM, struct drm_etnaviv_param)
#define DRM_IOCTL_ETNAVIV_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_NEW, struct drm_etnaviv_gem_new)
@@ -225,6 +279,8 @@ struct drm_etnaviv_gem_wait {
#define DRM_IOCTL_ETNAVIV_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_WAIT_FENCE, struct drm_etnaviv_wait_fence)
#define DRM_IOCTL_ETNAVIV_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_USERPTR, struct drm_etnaviv_gem_userptr)
#define DRM_IOCTL_ETNAVIV_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_WAIT, struct drm_etnaviv_gem_wait)
+#define DRM_IOCTL_ETNAVIV_PM_QUERY_DOM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_DOM, struct drm_etnaviv_pm_domain)
+#define DRM_IOCTL_ETNAVIV_PM_QUERY_SIG DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_SIG, struct drm_etnaviv_pm_signal)
#if defined(__cplusplus)
}
diff --git a/etnaviv/etnaviv_drmif.h b/etnaviv/etnaviv_drmif.h
index 8119baad..5a6bef8d 100644
--- a/etnaviv/etnaviv_drmif.h
+++ b/etnaviv/etnaviv_drmif.h
@@ -35,6 +35,9 @@ struct etna_pipe;
struct etna_gpu;
struct etna_device;
struct etna_cmd_stream;
+struct etna_perfmon;
+struct etna_perfmon_domain;
+struct etna_perfmon_signal;
enum etna_pipe_id {
ETNA_PIPE_3D = 0,
@@ -142,6 +145,8 @@ struct etna_cmd_stream *etna_cmd_stream_new(struct etna_pipe *pipe, uint32_t siz
void etna_cmd_stream_del(struct etna_cmd_stream *stream);
uint32_t etna_cmd_stream_timestamp(struct etna_cmd_stream *stream);
void etna_cmd_stream_flush(struct etna_cmd_stream *stream);
+void etna_cmd_stream_flush2(struct etna_cmd_stream *stream, int in_fence_fd,
+ int *out_fence_fd);
void etna_cmd_stream_finish(struct etna_cmd_stream *stream);
static inline uint32_t etna_cmd_stream_avail(struct etna_cmd_stream *stream)
@@ -188,4 +193,24 @@ struct etna_reloc {
void etna_cmd_stream_reloc(struct etna_cmd_stream *stream, const struct etna_reloc *r);
+/* performance monitoring functions:
+ */
+
+struct etna_perfmon *etna_perfmon_create(struct etna_pipe *pipe);
+void etna_perfmon_del(struct etna_perfmon *perfmon);
+struct etna_perfmon_domain *etna_perfmon_get_dom_by_name(struct etna_perfmon *pm, const char *name);
+struct etna_perfmon_signal *etna_perfmon_get_sig_by_name(struct etna_perfmon_domain *dom, const char *name);
+
+struct etna_perf {
+#define ETNA_PM_PROCESS_PRE 0x0001
+#define ETNA_PM_PROCESS_POST 0x0002
+ uint32_t flags;
+ uint32_t sequence;
+ struct etna_perfmon_signal *signal;
+ struct etna_bo *bo;
+ uint32_t offset;
+};
+
+void etna_cmd_stream_perf(struct etna_cmd_stream *stream, const struct etna_perf *p);
+
#endif /* ETNAVIV_DRMIF_H_ */
diff --git a/etnaviv/etnaviv_gpu.c b/etnaviv/etnaviv_gpu.c
index 35dec6cd..dc4c126d 100644
--- a/etnaviv/etnaviv_gpu.c
+++ b/etnaviv/etnaviv_gpu.c
@@ -24,10 +24,6 @@
* Christian Gmeiner <christian.gmeiner@gmail.com>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "etnaviv_priv.h"
#include "etnaviv_drmif.h"
@@ -48,7 +44,7 @@ static uint64_t get_param(struct etna_device *dev, uint32_t core, uint32_t param
return req.value;
}
-struct etna_gpu *etna_gpu_new(struct etna_device *dev, unsigned int core)
+drm_public struct etna_gpu *etna_gpu_new(struct etna_device *dev, unsigned int core)
{
struct etna_gpu *gpu;
@@ -61,32 +57,13 @@ struct etna_gpu *etna_gpu_new(struct etna_device *dev, unsigned int core)
gpu->dev = dev;
gpu->core = core;
- /* get specs from kernel space */
- gpu->specs.model = get_param(dev, core, ETNAVIV_PARAM_GPU_MODEL);
- gpu->specs.revision = get_param(dev, core, ETNAVIV_PARAM_GPU_REVISION);
- gpu->specs.features[0] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_0);
- gpu->specs.features[1] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_1);
- gpu->specs.features[2] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_2);
- gpu->specs.features[3] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_3);
- gpu->specs.features[4] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_4);
- gpu->specs.features[5] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_5);
- gpu->specs.features[6] = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_6);
- gpu->specs.stream_count = get_param(dev, core, ETNA_GPU_STREAM_COUNT);
- gpu->specs.register_max = get_param(dev, core, ETNA_GPU_REGISTER_MAX);
- gpu->specs.thread_count = get_param(dev, core, ETNA_GPU_THREAD_COUNT);
- gpu->specs.vertex_cache_size = get_param(dev, core, ETNA_GPU_VERTEX_CACHE_SIZE);
- gpu->specs.shader_core_count = get_param(dev, core, ETNA_GPU_SHADER_CORE_COUNT);
- gpu->specs.pixel_pipes = get_param(dev, core, ETNA_GPU_PIXEL_PIPES);
- gpu->specs.vertex_output_buffer_size = get_param(dev, core, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE);
- gpu->specs.buffer_size = get_param(dev, core, ETNA_GPU_BUFFER_SIZE);
- gpu->specs.instruction_count = get_param(dev, core, ETNA_GPU_INSTRUCTION_COUNT);
- gpu->specs.num_constants = get_param(dev, core, ETNA_GPU_NUM_CONSTANTS);
- gpu->specs.num_varyings = get_param(dev, core, ETNA_GPU_NUM_VARYINGS);
-
- if (!gpu->specs.model)
+ gpu->model = get_param(dev, core, ETNAVIV_PARAM_GPU_MODEL);
+ gpu->revision = get_param(dev, core, ETNAVIV_PARAM_GPU_REVISION);
+
+ if (!gpu->model)
goto fail;
- INFO_MSG(" GPU model: 0x%x (rev %x)", gpu->specs.model, gpu->specs.revision);
+ INFO_MSG(" GPU model: 0x%x (rev %x)", gpu->model, gpu->revision);
return gpu;
fail:
@@ -96,74 +73,77 @@ fail:
return NULL;
}
-void etna_gpu_del(struct etna_gpu *gpu)
+drm_public void etna_gpu_del(struct etna_gpu *gpu)
{
free(gpu);
}
-int etna_gpu_get_param(struct etna_gpu *gpu, enum etna_param_id param,
+drm_public int etna_gpu_get_param(struct etna_gpu *gpu, enum etna_param_id param,
uint64_t *value)
{
+ struct etna_device *dev = gpu->dev;
+ unsigned int core = gpu->core;
+
switch(param) {
case ETNA_GPU_MODEL:
- *value = gpu->specs.model;
+ *value = gpu->model;
return 0;
case ETNA_GPU_REVISION:
- *value = gpu->specs.revision;
+ *value = gpu->revision;
return 0;
case ETNA_GPU_FEATURES_0:
- *value = gpu->specs.features[0];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_0);
return 0;
case ETNA_GPU_FEATURES_1:
- *value = gpu->specs.features[1];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_1);
return 0;
case ETNA_GPU_FEATURES_2:
- *value = gpu->specs.features[2];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_2);
return 0;
case ETNA_GPU_FEATURES_3:
- *value = gpu->specs.features[3];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_3);
return 0;
case ETNA_GPU_FEATURES_4:
- *value = gpu->specs.features[4];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_4);
return 0;
case ETNA_GPU_FEATURES_5:
- *value = gpu->specs.features[5];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_5);
return 0;
case ETNA_GPU_FEATURES_6:
- *value = gpu->specs.features[6];
+ *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_6);
return 0;
case ETNA_GPU_STREAM_COUNT:
- *value = gpu->specs.stream_count;
+ *value = get_param(dev, core, ETNA_GPU_STREAM_COUNT);
return 0;
case ETNA_GPU_REGISTER_MAX:
- *value = gpu->specs.register_max;
+ *value = get_param(dev, core, ETNA_GPU_REGISTER_MAX);
return 0;
case ETNA_GPU_THREAD_COUNT:
- *value = gpu->specs.thread_count;
+ *value = get_param(dev, core, ETNA_GPU_THREAD_COUNT);
return 0;
case ETNA_GPU_VERTEX_CACHE_SIZE:
- *value = gpu->specs.vertex_cache_size;
+ *value = get_param(dev, core, ETNA_GPU_VERTEX_CACHE_SIZE);
return 0;
case ETNA_GPU_SHADER_CORE_COUNT:
- *value = gpu->specs.shader_core_count;
+ *value = get_param(dev, core, ETNA_GPU_SHADER_CORE_COUNT);
return 0;
case ETNA_GPU_PIXEL_PIPES:
- *value = gpu->specs.pixel_pipes;
+ *value = get_param(dev, core, ETNA_GPU_PIXEL_PIPES);
return 0;
case ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE:
- *value = gpu->specs.vertex_output_buffer_size;
+ *value = get_param(dev, core, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE);
return 0;
case ETNA_GPU_BUFFER_SIZE:
- *value = gpu->specs.buffer_size;
+ *value = get_param(dev, core, ETNA_GPU_BUFFER_SIZE);
return 0;
case ETNA_GPU_INSTRUCTION_COUNT:
- *value = gpu->specs.instruction_count;
+ *value = get_param(dev, core, ETNA_GPU_INSTRUCTION_COUNT);
return 0;
case ETNA_GPU_NUM_CONSTANTS:
- *value = gpu->specs.num_constants;
+ *value = get_param(dev, core, ETNA_GPU_NUM_CONSTANTS);
return 0;
case ETNA_GPU_NUM_VARYINGS:
- *value = gpu->specs.num_varyings;
+ *value = get_param(dev, core, ETNA_GPU_NUM_VARYINGS);
return 0;
default:
diff --git a/etnaviv/etnaviv_perfmon.c b/etnaviv/etnaviv_perfmon.c
new file mode 100644
index 00000000..f6576b8a
--- /dev/null
+++ b/etnaviv/etnaviv_perfmon.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2017 Etnaviv Project
+ * Copyright (C) 2017 Zodiac Inflight Innovations
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Christian Gmeiner <christian.gmeiner@gmail.com>
+ */
+
+#include "etnaviv_priv.h"
+
+static int etna_perfmon_query_signals(struct etna_perfmon *pm, struct etna_perfmon_domain *dom)
+{
+ struct etna_device *dev = pm->pipe->gpu->dev;
+ struct drm_etnaviv_pm_signal req = {
+ .pipe = pm->pipe->id,
+ .domain = dom->id
+ };
+
+ do {
+ struct etna_perfmon_signal *sig;
+ int ret;
+
+ ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_SIG, &req, sizeof(req));
+ if (ret)
+ break;
+
+ sig = calloc(1, sizeof(*sig));
+ if (!sig)
+ return -ENOMEM;
+
+ INFO_MSG("perfmon signal:");
+ INFO_MSG("id = %d", req.id);
+ INFO_MSG("name = %s", req.name);
+
+ sig->domain = dom;
+ sig->signal = req.id;
+ strncpy(sig->name, req.name, sizeof(sig->name));
+ list_addtail(&sig->head, &dom->signals);
+ } while (req.iter != 0xffff);
+
+ return 0;
+}
+
+static int etna_perfmon_query_domains(struct etna_perfmon *pm)
+{
+ struct etna_device *dev = pm->pipe->gpu->dev;
+ struct drm_etnaviv_pm_domain req = {
+ .pipe = pm->pipe->id
+ };
+
+ do {
+ struct etna_perfmon_domain *dom;
+ int ret;
+
+ ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_PM_QUERY_DOM, &req, sizeof(req));
+ if (ret)
+ break;
+
+ dom = calloc(1, sizeof(*dom));
+ if (!dom)
+ return -ENOMEM;
+
+ list_inithead(&dom->signals);
+ dom->id = req.id;
+ strncpy(dom->name, req.name, sizeof(dom->name));
+ list_addtail(&dom->head, &pm->domains);
+
+ INFO_MSG("perfmon domain:");
+ INFO_MSG("id = %d", req.id);
+ INFO_MSG("name = %s", req.name);
+ INFO_MSG("nr_signals = %d", req.nr_signals);
+
+ /* Query all available signals for this domain. */
+ if (req.nr_signals > 0) {
+ ret = etna_perfmon_query_signals(pm, dom);
+ if (ret)
+ return ret;
+ }
+ } while (req.iter != 0xff);
+
+ return 0;
+}
+
+static void etna_perfmon_free_signals(struct etna_perfmon_domain *dom)
+{
+ struct etna_perfmon_signal *sig, *next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(sig, next, &dom->signals, head) {
+ list_del(&sig->head);
+ free(sig);
+ }
+}
+
+static void etna_perfmon_free_domains(struct etna_perfmon *pm)
+{
+ struct etna_perfmon_domain *dom, *next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(dom, next, &pm->domains, head) {
+ etna_perfmon_free_signals(dom);
+ list_del(&dom->head);
+ free(dom);
+ }
+}
+
+drm_public struct etna_perfmon *etna_perfmon_create(struct etna_pipe *pipe)
+{
+ struct etna_perfmon *pm;
+ int ret;
+
+ pm = calloc(1, sizeof(*pm));
+ if (!pm) {
+ ERROR_MSG("allocation failed");
+ return NULL;
+ }
+
+ list_inithead(&pm->domains);
+ pm->pipe = pipe;
+
+ /* query all available domains and sources for this device */
+ ret = etna_perfmon_query_domains(pm);
+ if (ret)
+ goto fail;
+
+ return pm;
+
+fail:
+ etna_perfmon_del(pm);
+ return NULL;
+}
+
+drm_public void etna_perfmon_del(struct etna_perfmon *pm)
+{
+ if (!pm)
+ return;
+
+ etna_perfmon_free_domains(pm);
+ free(pm);
+}
+
+drm_public struct etna_perfmon_domain *etna_perfmon_get_dom_by_name(struct etna_perfmon *pm, const char *name)
+{
+ struct etna_perfmon_domain *dom;
+
+ if (pm) {
+ LIST_FOR_EACH_ENTRY(dom, &pm->domains, head) {
+ if (!strcmp(dom->name, name))
+ return dom;
+ }
+ }
+
+ return NULL;
+}
+
+drm_public struct etna_perfmon_signal *etna_perfmon_get_sig_by_name(struct etna_perfmon_domain *dom, const char *name)
+{
+ struct etna_perfmon_signal *signal;
+
+ if (dom) {
+ LIST_FOR_EACH_ENTRY(signal, &dom->signals, head) {
+ if (!strcmp(signal->name, name))
+ return signal;
+ }
+ }
+
+ return NULL;
+}
diff --git a/etnaviv/etnaviv_pipe.c b/etnaviv/etnaviv_pipe.c
index 94c5d377..4120a36f 100644
--- a/etnaviv/etnaviv_pipe.c
+++ b/etnaviv/etnaviv_pipe.c
@@ -24,18 +24,14 @@
* Christian Gmeiner <christian.gmeiner@gmail.com>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "etnaviv_priv.h"
-int etna_pipe_wait(struct etna_pipe *pipe, uint32_t timestamp, uint32_t ms)
+drm_public int etna_pipe_wait(struct etna_pipe *pipe, uint32_t timestamp, uint32_t ms)
{
return etna_pipe_wait_ns(pipe, timestamp, ms * 1000000);
}
-int etna_pipe_wait_ns(struct etna_pipe *pipe, uint32_t timestamp, uint64_t ns)
+drm_public int etna_pipe_wait_ns(struct etna_pipe *pipe, uint32_t timestamp, uint64_t ns)
{
struct etna_device *dev = pipe->gpu->dev;
int ret;
@@ -59,12 +55,12 @@ int etna_pipe_wait_ns(struct etna_pipe *pipe, uint32_t timestamp, uint64_t ns)
return 0;
}
-void etna_pipe_del(struct etna_pipe *pipe)
+drm_public void etna_pipe_del(struct etna_pipe *pipe)
{
free(pipe);
}
-struct etna_pipe *etna_pipe_new(struct etna_gpu *gpu, enum etna_pipe_id id)
+drm_public struct etna_pipe *etna_pipe_new(struct etna_gpu *gpu, enum etna_pipe_id id)
{
struct etna_pipe *pipe;
diff --git a/etnaviv/etnaviv_priv.h b/etnaviv/etnaviv_priv.h
index feaa5ad9..e45d364c 100644
--- a/etnaviv/etnaviv_priv.h
+++ b/etnaviv/etnaviv_priv.h
@@ -47,25 +47,6 @@
#include "etnaviv_drmif.h"
#include "etnaviv_drm.h"
-#define VIV_FEATURES_WORD_COUNT 7
-
-struct etna_specs {
- uint32_t model;
- uint32_t revision;
- uint32_t features[VIV_FEATURES_WORD_COUNT];
- uint32_t stream_count;
- uint32_t register_max;
- uint32_t thread_count;
- uint32_t shader_core_count;
- uint32_t vertex_cache_size;
- uint32_t vertex_output_buffer_size;
- uint32_t pixel_pipes;
- uint32_t instruction_count;
- uint32_t num_constants;
- uint32_t num_varyings;
- uint32_t buffer_size;
-};
-
struct etna_bo_bucket {
uint32_t size;
struct list_head list;
@@ -134,8 +115,9 @@ struct etna_bo {
struct etna_gpu {
struct etna_device *dev;
- struct etna_specs specs;
uint32_t core;
+ uint32_t model;
+ uint32_t revision;
};
struct etna_pipe {
@@ -158,6 +140,10 @@ struct etna_cmd_stream_priv {
/* reloc's table: */
struct drm_etnaviv_gem_submit_reloc *relocs;
uint32_t nr_relocs, max_relocs;
+
+ /* perf's table: */
+ struct drm_etnaviv_gem_submit_pmr *pmrs;
+ uint32_t nr_pmrs, max_pmrs;
} submit;
/* should have matching entries in submit.bos: */
@@ -169,6 +155,27 @@ struct etna_cmd_stream_priv {
void *reset_notify_priv;
};
+struct etna_perfmon {
+ struct list_head domains;
+ struct etna_pipe *pipe;
+};
+
+struct etna_perfmon_domain
+{
+ struct list_head head;
+ struct list_head signals;
+ uint8_t id;
+ char name[64];
+};
+
+struct etna_perfmon_signal
+{
+ struct list_head head;
+ struct etna_perfmon_domain *domain;
+ uint8_t signal;
+ char name[64];
+};
+
#define ALIGN(v,a) (((v) + (a) - 1) & ~((a) - 1))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
diff --git a/etnaviv/meson.build b/etnaviv/meson.build
new file mode 100644
index 00000000..515a4ed0
--- /dev/null
+++ b/etnaviv/meson.build
@@ -0,0 +1,59 @@
+# 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.
+
+
+libdrm_etnaviv = shared_library(
+ 'drm_etnaviv',
+ [
+ files(
+ 'etnaviv_device.c', 'etnaviv_gpu.c', 'etnaviv_bo.c', 'etnaviv_bo_cache.c',
+ 'etnaviv_perfmon.c', 'etnaviv_pipe.c', 'etnaviv_cmd_stream.c',
+ ),
+ config_file
+ ],
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ c_args : libdrm_c_args,
+ dependencies : [dep_pthread_stubs, dep_rt, dep_atomic_ops],
+ version : '1.0.0',
+ install : true,
+)
+
+install_headers('etnaviv_drmif.h', subdir : 'libdrm')
+
+pkg.generate(
+ name : 'libdrm_etnaviv',
+ libraries : libdrm_etnaviv,
+ subdirs : ['.', 'libdrm'],
+ version : meson.project_version(),
+ requires_private : 'libdrm',
+ description : 'Userspace interface to Tegra kernel DRM services',
+)
+
+ext_libdrm_etnaviv = declare_dependency(
+ link_with : [libdrm, libdrm_etnaviv],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+test(
+ 'etnaviv-symbol-check',
+ prog_bash,
+ args : [files('etnaviv-symbol-check'), libdrm_etnaviv]
+)
diff --git a/exynos/Makefile.am b/exynos/Makefile.am
index f99f8981..76b185d3 100644
--- a/exynos/Makefile.am
+++ b/exynos/Makefile.am
@@ -1,5 +1,6 @@
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
@@ -23,5 +24,6 @@ libdrm_exynosinclude_HEADERS = exynos_drmif.h
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_exynos.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = exynos-symbol-check
EXTRA_DIST = $(TESTS)
diff --git a/exynos/exynos-symbol-check b/exynos/exynos-symbol-check
index 9692caa6..49d611e6 100755
--- a/exynos/exynos-symbol-check
+++ b/exynos/exynos-symbol-check
@@ -1,9 +1,11 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.am/libdrm_exynos*_HEADERS
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_exynos.so} | awk '{print $3}'| while read func; do
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_exynos.so} | awk '{print $3}'| while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
__bss_start
_edata
diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c
index b961e520..078bf2c5 100644
--- a/exynos/exynos_drm.c
+++ b/exynos/exynos_drm.c
@@ -24,10 +24,6 @@
* Inki Dae <inki.dae@samsung.com>
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -52,7 +48,7 @@
*
* if true, return the device object else NULL.
*/
-struct exynos_device * exynos_device_create(int fd)
+drm_public struct exynos_device * exynos_device_create(int fd)
{
struct exynos_device *dev;
@@ -73,7 +69,7 @@ struct exynos_device * exynos_device_create(int fd)
*
* @dev: exynos drm device object.
*/
-void exynos_device_destroy(struct exynos_device *dev)
+drm_public void exynos_device_destroy(struct exynos_device *dev)
{
free(dev);
}
@@ -91,8 +87,8 @@ void exynos_device_destroy(struct exynos_device *dev)
*
* if true, return a exynos buffer object else NULL.
*/
-struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
- size_t size, uint32_t flags)
+drm_public struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
+ size_t size, uint32_t flags)
{
struct exynos_bo *bo;
struct drm_exynos_gem_create req = {
@@ -145,8 +141,8 @@ fail:
*
* if true, return 0 else negative.
*/
-int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
- size_t *size, uint32_t *flags)
+drm_public int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
+ size_t *size, uint32_t *flags)
{
int ret;
struct drm_exynos_gem_info req = {
@@ -171,7 +167,7 @@ int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
*
* @bo: a exynos buffer object to be destroyed.
*/
-void exynos_bo_destroy(struct exynos_bo *bo)
+drm_public void exynos_bo_destroy(struct exynos_bo *bo)
{
if (!bo)
return;
@@ -203,7 +199,7 @@ void exynos_bo_destroy(struct exynos_bo *bo)
* if true, return a exynos buffer object else NULL.
*
*/
-struct exynos_bo *
+drm_public struct exynos_bo *
exynos_bo_from_name(struct exynos_device *dev, uint32_t name)
{
struct exynos_bo *bo;
@@ -246,7 +242,7 @@ err_free_bo:
*
* if true, return 0 else negative.
*/
-int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name)
+drm_public int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name)
{
if (!bo->name) {
struct drm_gem_flink req = {
@@ -269,7 +265,7 @@ int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name)
return 0;
}
-uint32_t exynos_bo_handle(struct exynos_bo *bo)
+drm_public uint32_t exynos_bo_handle(struct exynos_bo *bo)
{
return bo->handle;
}
@@ -282,7 +278,7 @@ uint32_t exynos_bo_handle(struct exynos_bo *bo)
*
* if true, user pointer mmaped else NULL.
*/
-void *exynos_bo_map(struct exynos_bo *bo)
+drm_public void *exynos_bo_map(struct exynos_bo *bo)
{
if (!bo->vaddr) {
struct exynos_device *dev = bo->dev;
@@ -319,7 +315,7 @@ void *exynos_bo_map(struct exynos_bo *bo)
*
* @return: 0 on success, -1 on error, and errno will be set
*/
-int
+drm_public int
exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle, int *fd)
{
return drmPrimeHandleToFD(dev->fd, handle, 0, fd);
@@ -334,7 +330,7 @@ exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle, int *fd)
*
* @return: 0 on success, -1 on error, and errno will be set
*/
-int
+drm_public int
exynos_prime_fd_to_handle(struct exynos_device *dev, int fd, uint32_t *handle)
{
return drmPrimeFDToHandle(dev->fd, fd, handle);
@@ -357,7 +353,7 @@ exynos_prime_fd_to_handle(struct exynos_device *dev, int fd, uint32_t *handle)
*
* if true, return 0 else negative.
*/
-int
+drm_public int
exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
uint32_t ext, void *edid)
{
@@ -398,7 +394,7 @@ exynos_handle_vendor(int fd, struct drm_event *e, void *ctx)
}
}
-int
+drm_public int
exynos_handle_event(struct exynos_device *dev, struct exynos_event_context *ctx)
{
char buffer[1024];
@@ -417,7 +413,7 @@ exynos_handle_event(struct exynos_device *dev, struct exynos_event_context *ctx)
i = 0;
while (i < len) {
- e = (struct drm_event *) &buffer[i];
+ e = (struct drm_event *)(buffer + i);
switch (e->type) {
case DRM_EVENT_VBLANK:
if (evctx->version < 1 ||
diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h
index 626e3998..154439bb 100644
--- a/exynos/exynos_drmif.h
+++ b/exynos/exynos_drmif.h
@@ -31,6 +31,10 @@
#include <stdint.h>
#include "exynos_drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
struct exynos_device {
int fd;
};
@@ -109,4 +113,8 @@ int exynos_handle_event(struct exynos_device *dev,
struct exynos_event_context *ctx);
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* EXYNOS_DRMIF_H_ */
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c
index 7f1d105a..ac6fa687 100644
--- a/exynos/exynos_fimg2d.c
+++ b/exynos/exynos_fimg2d.c
@@ -3,17 +3,26 @@
* Authors:
* Inki Dae <inki.dae@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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
+ * VA LINUX SYSTEMS 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 HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -293,20 +302,6 @@ static void g2d_set_direction(struct g2d_context *ctx,
}
/*
- * g2d_reset - reset fimg2d hardware.
- *
- * @ctx: a pointer to g2d_context structure.
- *
- */
-static void g2d_reset(struct g2d_context *ctx)
-{
- ctx->cmd_nr = 0;
- ctx->cmd_buf_nr = 0;
-
- g2d_add_cmd(ctx, SOFT_RESET_REG, 0x01);
-}
-
-/*
* g2d_flush - submit all commands and values in user side command buffer
* to command queue aware of fimg2d dma.
*
@@ -361,7 +356,7 @@ static int g2d_flush(struct g2d_context *ctx)
*
* fd: a file descriptor to an opened drm device.
*/
-struct g2d_context *g2d_init(int fd)
+drm_public struct g2d_context *g2d_init(int fd)
{
struct drm_exynos_g2d_get_ver ver;
struct g2d_context *ctx;
@@ -389,7 +384,7 @@ struct g2d_context *g2d_init(int fd)
return ctx;
}
-void g2d_fini(struct g2d_context *ctx)
+drm_public void g2d_fini(struct g2d_context *ctx)
{
free(ctx);
}
@@ -405,7 +400,7 @@ void g2d_fini(struct g2d_context *ctx)
* @ctx: a pointer to g2d_context structure.
* @userdata: a pointer to the user data
*/
-void g2d_config_event(struct g2d_context *ctx, void *userdata)
+drm_public void g2d_config_event(struct g2d_context *ctx, void *userdata)
{
ctx->event_userdata = userdata;
}
@@ -415,7 +410,7 @@ void g2d_config_event(struct g2d_context *ctx, void *userdata)
*
* @ctx: a pointer to g2d_context structure.
*/
-int g2d_exec(struct g2d_context *ctx)
+drm_public int g2d_exec(struct g2d_context *ctx)
{
struct drm_exynos_g2d_exec exec;
int ret;
@@ -447,7 +442,7 @@ int g2d_exec(struct g2d_context *ctx)
* @w: width value to buffer filled with given color data.
* @h: height value to buffer filled with given color data.
*/
-int
+drm_public int
g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
unsigned int x, unsigned int y, unsigned int w,
unsigned int h)
@@ -500,7 +495,7 @@ g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
* @w: width value to source and destination buffers.
* @h: height value to source and destination buffers.
*/
-int
+drm_public int
g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
struct g2d_image *dst, unsigned int src_x, unsigned int src_y,
unsigned int dst_x, unsigned dst_y, unsigned int w,
@@ -583,7 +578,7 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
* @w: width of rectangle to move.
* @h: height of rectangle to move.
*/
-int
+drm_public int
g2d_move(struct g2d_context *ctx, struct g2d_image *img,
unsigned int src_x, unsigned int src_y,
unsigned int dst_x, unsigned dst_y, unsigned int w,
@@ -681,7 +676,7 @@ g2d_move(struct g2d_context *ctx, struct g2d_image *img,
* @negative: indicate that it uses color negative to source and
* destination buffers.
*/
-int
+drm_public int
g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
struct g2d_image *dst, unsigned int src_x,
unsigned int src_y, unsigned int src_w,
@@ -790,7 +785,7 @@ g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
* @h: height value to source and destination buffer.
* @op: blend operation type.
*/
-int
+drm_public int
g2d_blend(struct g2d_context *ctx, struct g2d_image *src,
struct g2d_image *dst, unsigned int src_x,
unsigned int src_y, unsigned int dst_x, unsigned int dst_y,
@@ -907,7 +902,7 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src,
* @dst_h: height value to destination buffer.
* @op: blend operation type.
*/
-int
+drm_public int
g2d_scale_and_blend(struct g2d_context *ctx, struct g2d_image *src,
struct g2d_image *dst, unsigned int src_x, unsigned int src_y,
unsigned int src_w, unsigned int src_h, unsigned int dst_x,
diff --git a/exynos/exynos_fimg2d.h b/exynos/exynos_fimg2d.h
index a825c683..a4dfbe73 100644
--- a/exynos/exynos_fimg2d.h
+++ b/exynos/exynos_fimg2d.h
@@ -3,11 +3,24 @@
* Authors:
* Inki Dae <inki.dae@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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
+ * VA LINUX SYSTEMS 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 _FIMG2D_H_
diff --git a/exynos/fimg2d_reg.h b/exynos/fimg2d_reg.h
index 07dd6349..d42296d4 100644
--- a/exynos/fimg2d_reg.h
+++ b/exynos/fimg2d_reg.h
@@ -3,11 +3,24 @@
* Authors:
* Inki Dae <inki.dae@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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
+ * VA LINUX SYSTEMS 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 _FIMG2D_REG_H_
diff --git a/exynos/meson.build b/exynos/meson.build
new file mode 100644
index 00000000..bdfc3fc6
--- /dev/null
+++ b/exynos/meson.build
@@ -0,0 +1,54 @@
+# 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.
+
+libdrm_exynos = shared_library(
+ 'drm_exynos',
+ [files('exynos_drm.c', 'exynos_fimg2d.c'), config_file],
+ c_args : libdrm_c_args,
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ dependencies : [dep_pthread_stubs],
+ version : '1.0.0',
+ install : true,
+)
+
+install_headers('exynos_drmif.h', subdir : 'libdrm')
+install_headers('exynos_drm.h', 'exynos_fimg2d.h', subdir : 'exynos')
+
+ext_libdrm_exynos = declare_dependency(
+ link_with : [libdrm, libdrm_exynos],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+pkg.generate(
+ name : 'libdrm_exynos',
+ libraries : libdrm_exynos,
+ subdirs : ['.', 'libdrm', 'exynos'],
+ version : '0.7',
+ requires_private : 'libdrm',
+ description : 'Userspace interface to exynos kernel DRM services',
+)
+
+test(
+ 'exynos-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('exynos-symbol-check'), libdrm_exynos]
+)
diff --git a/freedreno/Makefile.am b/freedreno/Makefile.am
index 0771d146..37845035 100644
--- a/freedreno/Makefile.am
+++ b/freedreno/Makefile.am
@@ -3,8 +3,10 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
+ $(VALGRIND_CFLAGS) \
-I$(top_srcdir)/include/drm
libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la
@@ -26,5 +28,6 @@ libdrm_freedrenocommoninclude_HEADERS = $(LIBDRM_FREEDRENO_H_FILES)
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_freedreno.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = freedreno-symbol-check
EXTRA_DIST = $(TESTS)
diff --git a/freedreno/Makefile.sources b/freedreno/Makefile.sources
index 68a679bf..ca89511a 100644
--- a/freedreno/Makefile.sources
+++ b/freedreno/Makefile.sources
@@ -7,7 +7,6 @@ LIBDRM_FREEDRENO_FILES := \
freedreno_bo_cache.c \
msm/msm_bo.c \
msm/msm_device.c \
- msm/msm_drm.h \
msm/msm_pipe.c \
msm/msm_priv.h \
msm/msm_ringbuffer.c
diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbol-check
index 42f2c439..978026c0 100755
--- a/freedreno/freedreno-symbol-check
+++ b/freedreno/freedreno-symbol-check
@@ -1,9 +1,11 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.sources/LIBDRM_FREEDRENO_H_FILES
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
__bss_start
_edata
@@ -18,10 +20,12 @@ fd_bo_from_dmabuf
fd_bo_from_fbdev
fd_bo_from_handle
fd_bo_from_name
+fd_bo_get_iova
fd_bo_get_name
fd_bo_handle
fd_bo_map
fd_bo_new
+fd_bo_put_iova
fd_bo_ref
fd_bo_size
fd_device_del
@@ -33,6 +37,8 @@ fd_device_version
fd_pipe_del
fd_pipe_get_param
fd_pipe_new
+fd_pipe_new2
+fd_pipe_ref
fd_pipe_wait
fd_pipe_wait_timeout
fd_ringbuffer_cmd_count
@@ -42,17 +48,16 @@ fd_ringbuffer_emit_reloc_ring_full
fd_ringbuffer_flush
fd_ringbuffer_grow
fd_ringbuffer_new
+fd_ringbuffer_new_flags
+fd_ringbuffer_new_object
+fd_ringbuffer_ref
fd_ringbuffer_reloc
fd_ringbuffer_reloc2
fd_ringbuffer_reset
fd_ringbuffer_set_parent
+fd_ringbuffer_size
fd_ringbuffer_timestamp
-fd_ringmarker_del
-fd_ringmarker_dwords
-fd_ringmarker_flush
fd_ringbuffer_flush2
-fd_ringmarker_mark
-fd_ringmarker_new
EOF
done)
diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c
index 996d6b95..efc5b71f 100644
--- a/freedreno/freedreno_bo.c
+++ b/freedreno/freedreno_bo.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "freedreno_drmif.h"
#include "freedreno_priv.h"
@@ -82,14 +78,15 @@ static struct fd_bo * bo_from_handle(struct fd_device *dev,
return bo;
}
-struct fd_bo *
-fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
+static struct fd_bo *
+bo_new(struct fd_device *dev, uint32_t size, uint32_t flags,
+ struct fd_bo_cache *cache)
{
struct fd_bo *bo = NULL;
uint32_t handle;
int ret;
- bo = fd_bo_cache_alloc(&dev->bo_cache, &size, flags);
+ bo = fd_bo_cache_alloc(cache, &size, flags);
if (bo)
return bo;
@@ -99,13 +96,37 @@ fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
pthread_mutex_lock(&table_lock);
bo = bo_from_handle(dev, size, handle);
- bo->bo_reuse = TRUE;
pthread_mutex_unlock(&table_lock);
+ VG_BO_ALLOC(bo);
+
return bo;
}
-struct fd_bo *
+drm_public struct fd_bo *
+fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
+{
+ struct fd_bo *bo = bo_new(dev, size, flags, &dev->bo_cache);
+ if (bo)
+ bo->bo_reuse = BO_CACHE;
+ return bo;
+}
+
+/* internal function to allocate bo's that use the ringbuffer cache
+ * instead of the normal bo_cache. The purpose is, because cmdstream
+ * bo's get vmap'd on the kernel side, and that is expensive, we want
+ * to re-use cmdstream bo's for cmdstream and not unrelated purposes.
+ */
+drm_private struct fd_bo *
+fd_bo_new_ring(struct fd_device *dev, uint32_t size, uint32_t flags)
+{
+ struct fd_bo *bo = bo_new(dev, size, flags, &dev->ring_cache);
+ if (bo)
+ bo->bo_reuse = RING_CACHE;
+ return bo;
+}
+
+drm_public struct fd_bo *
fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size)
{
struct fd_bo *bo = NULL;
@@ -118,13 +139,15 @@ fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size)
bo = bo_from_handle(dev, size, handle);
+ VG_BO_ALLOC(bo);
+
out_unlock:
pthread_mutex_unlock(&table_lock);
return bo;
}
-struct fd_bo *
+drm_public struct fd_bo *
fd_bo_from_dmabuf(struct fd_device *dev, int fd)
{
int ret, size;
@@ -134,6 +157,7 @@ fd_bo_from_dmabuf(struct fd_device *dev, int fd)
pthread_mutex_lock(&table_lock);
ret = drmPrimeFDToHandle(dev->fd, fd, &handle);
if (ret) {
+ pthread_mutex_unlock(&table_lock);
return NULL;
}
@@ -147,13 +171,15 @@ fd_bo_from_dmabuf(struct fd_device *dev, int fd)
bo = bo_from_handle(dev, size, handle);
+ VG_BO_ALLOC(bo);
+
out_unlock:
pthread_mutex_unlock(&table_lock);
return bo;
}
-struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name)
+drm_public struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name)
{
struct drm_gem_open req = {
.name = name,
@@ -177,8 +203,10 @@ struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name)
goto out_unlock;
bo = bo_from_handle(dev, req.size, req.handle);
- if (bo)
+ if (bo) {
set_name(bo, name);
+ VG_BO_ALLOC(bo);
+ }
out_unlock:
pthread_mutex_unlock(&table_lock);
@@ -186,13 +214,23 @@ out_unlock:
return bo;
}
-struct fd_bo * fd_bo_ref(struct fd_bo *bo)
+drm_public uint64_t fd_bo_get_iova(struct fd_bo *bo)
+{
+ return bo->funcs->iova(bo);
+}
+
+drm_public void fd_bo_put_iova(struct fd_bo *bo)
+{
+ /* currently a no-op */
+}
+
+drm_public struct fd_bo * fd_bo_ref(struct fd_bo *bo)
{
atomic_inc(&bo->refcnt);
return bo;
}
-void fd_bo_del(struct fd_bo *bo)
+drm_public void fd_bo_del(struct fd_bo *bo)
{
struct fd_device *dev = bo->dev;
@@ -201,7 +239,9 @@ void fd_bo_del(struct fd_bo *bo)
pthread_mutex_lock(&table_lock);
- if (bo->bo_reuse && (fd_bo_cache_free(&dev->bo_cache, bo) == 0))
+ if ((bo->bo_reuse == BO_CACHE) && (fd_bo_cache_free(&dev->bo_cache, bo) == 0))
+ goto out;
+ if ((bo->bo_reuse == RING_CACHE) && (fd_bo_cache_free(&dev->ring_cache, bo) == 0))
goto out;
bo_del(bo);
@@ -213,6 +253,8 @@ out:
/* Called under table_lock */
drm_private void bo_del(struct fd_bo *bo)
{
+ VG_BO_FREE(bo);
+
if (bo->map)
drm_munmap(bo->map, bo->size);
@@ -233,7 +275,7 @@ drm_private void bo_del(struct fd_bo *bo)
bo->funcs->destroy(bo);
}
-int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
+drm_public int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
{
if (!bo->name) {
struct drm_gem_flink req = {
@@ -249,7 +291,7 @@ int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
pthread_mutex_lock(&table_lock);
set_name(bo, req.name);
pthread_mutex_unlock(&table_lock);
- bo->bo_reuse = FALSE;
+ bo->bo_reuse = NO_CACHE;
}
*name = bo->name;
@@ -257,12 +299,12 @@ int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
return 0;
}
-uint32_t fd_bo_handle(struct fd_bo *bo)
+drm_public uint32_t fd_bo_handle(struct fd_bo *bo)
{
return bo->handle;
}
-int fd_bo_dmabuf(struct fd_bo *bo)
+drm_public int fd_bo_dmabuf(struct fd_bo *bo)
{
int ret, prime_fd;
@@ -273,17 +315,17 @@ int fd_bo_dmabuf(struct fd_bo *bo)
return ret;
}
- bo->bo_reuse = FALSE;
+ bo->bo_reuse = NO_CACHE;
return prime_fd;
}
-uint32_t fd_bo_size(struct fd_bo *bo)
+drm_public uint32_t fd_bo_size(struct fd_bo *bo)
{
return bo->size;
}
-void * fd_bo_map(struct fd_bo *bo)
+drm_public void * fd_bo_map(struct fd_bo *bo)
{
if (!bo->map) {
uint64_t offset;
@@ -305,18 +347,18 @@ void * fd_bo_map(struct fd_bo *bo)
}
/* a bit odd to take the pipe as an arg, but it's a, umm, quirk of kgsl.. */
-int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
+drm_public int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
{
return bo->funcs->cpu_prep(bo, pipe, op);
}
-void fd_bo_cpu_fini(struct fd_bo *bo)
+drm_public void fd_bo_cpu_fini(struct fd_bo *bo)
{
bo->funcs->cpu_fini(bo);
}
-#ifndef HAVE_FREEDRENO_KGSL
-struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size)
+#if !HAVE_FREEDRENO_KGSL
+drm_public struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size)
{
return NULL;
}
diff --git a/freedreno/freedreno_bo_cache.c b/freedreno/freedreno_bo_cache.c
index 7becb0d6..bb0605ab 100644
--- a/freedreno/freedreno_bo_cache.c
+++ b/freedreno/freedreno_bo_cache.c
@@ -26,14 +26,9 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "freedreno_drmif.h"
#include "freedreno_priv.h"
-
drm_private void bo_del(struct fd_bo *bo);
drm_private extern pthread_mutex_t table_lock;
@@ -54,7 +49,7 @@ add_bucket(struct fd_bo_cache *cache, int size)
* fill in for a bit smoother size curve..
*/
drm_private void
-fd_bo_cache_init(struct fd_bo_cache *cache, int course)
+fd_bo_cache_init(struct fd_bo_cache *cache, int coarse)
{
unsigned long size, cache_max_size = 64 * 1024 * 1024;
@@ -68,13 +63,13 @@ fd_bo_cache_init(struct fd_bo_cache *cache, int course)
*/
add_bucket(cache, 4096);
add_bucket(cache, 4096 * 2);
- if (!course)
+ if (!coarse)
add_bucket(cache, 4096 * 3);
/* Initialize the linked lists for BO reuse cache. */
for (size = 4 * 4096; size <= cache_max_size; size *= 2) {
add_bucket(cache, size);
- if (!course) {
+ if (!coarse) {
add_bucket(cache, size + size * 1 / 4);
add_bucket(cache, size + size * 2 / 4);
add_bucket(cache, size + size * 3 / 4);
@@ -102,6 +97,7 @@ fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time)
if (time && ((time - bo->free_time) <= 1))
break;
+ VG_BO_OBTAIN(bo);
list_del(&bo->list);
bo_del(bo);
}
@@ -177,6 +173,7 @@ retry:
*size = bucket->size;
bo = find_in_bucket(bucket, flags);
if (bo) {
+ VG_BO_OBTAIN(bo);
if (bo->funcs->madvise(bo, TRUE) <= 0) {
/* we've lost the backing pages, delete and try again: */
pthread_mutex_lock(&table_lock);
@@ -207,6 +204,7 @@ fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo)
clock_gettime(CLOCK_MONOTONIC, &time);
bo->free_time = time.tv_sec;
+ VG_BO_RELEASE(bo);
list_addtail(&bo->list, &bucket->list);
fd_bo_cache_cleanup(cache, time.tv_sec);
diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c
index fcbf1402..ac234304 100644
--- a/freedreno/freedreno_device.c
+++ b/freedreno/freedreno_device.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -42,7 +38,7 @@ static pthread_mutex_t table_lock = PTHREAD_MUTEX_INITIALIZER;
struct fd_device * kgsl_device_new(int fd);
struct fd_device * msm_device_new(int fd);
-struct fd_device * fd_device_new(int fd)
+drm_public struct fd_device * fd_device_new(int fd)
{
struct fd_device *dev;
drmVersionPtr version;
@@ -65,7 +61,7 @@ struct fd_device * fd_device_new(int fd)
dev = msm_device_new(fd);
dev->version = version->version_minor;
-#ifdef HAVE_FREEDRENO_KGSL
+#if HAVE_FREEDRENO_KGSL
} else if (!strcmp(version->name, "kgsl")) {
DEBUG_MSG("kgsl DRM device");
dev = kgsl_device_new(fd);
@@ -86,6 +82,7 @@ out:
dev->handle_table = drmHashCreate();
dev->name_table = drmHashCreate();
fd_bo_cache_init(&dev->bo_cache, FALSE);
+ fd_bo_cache_init(&dev->ring_cache, TRUE);
return dev;
}
@@ -93,7 +90,7 @@ out:
/* like fd_device_new() but creates it's own private dup() of the fd
* which is close()d when the device is finalized.
*/
-struct fd_device * fd_device_new_dup(int fd)
+drm_public struct fd_device * fd_device_new_dup(int fd)
{
int dup_fd = dup(fd);
struct fd_device *dev = fd_device_new(dup_fd);
@@ -104,7 +101,7 @@ struct fd_device * fd_device_new_dup(int fd)
return dev;
}
-struct fd_device * fd_device_ref(struct fd_device *dev)
+drm_public struct fd_device * fd_device_ref(struct fd_device *dev)
{
atomic_inc(&dev->refcnt);
return dev;
@@ -112,12 +109,13 @@ struct fd_device * fd_device_ref(struct fd_device *dev)
static void fd_device_del_impl(struct fd_device *dev)
{
+ int close_fd = dev->closefd ? dev->fd : -1;
fd_bo_cache_cleanup(&dev->bo_cache, 0);
drmHashDestroy(dev->handle_table);
drmHashDestroy(dev->name_table);
- if (dev->closefd)
- close(dev->fd);
dev->funcs->destroy(dev);
+ if (close_fd >= 0)
+ close(close_fd);
}
drm_private void fd_device_del_locked(struct fd_device *dev)
@@ -127,7 +125,7 @@ drm_private void fd_device_del_locked(struct fd_device *dev)
fd_device_del_impl(dev);
}
-void fd_device_del(struct fd_device *dev)
+drm_public void fd_device_del(struct fd_device *dev)
{
if (!atomic_dec_and_test(&dev->refcnt))
return;
@@ -136,12 +134,12 @@ void fd_device_del(struct fd_device *dev)
pthread_mutex_unlock(&table_lock);
}
-int fd_device_fd(struct fd_device *dev)
+drm_public int fd_device_fd(struct fd_device *dev)
{
return dev->fd;
}
-enum fd_version fd_device_version(struct fd_device *dev)
+drm_public enum fd_version fd_device_version(struct fd_device *dev)
{
return dev->version;
}
diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h
index 7a8073ff..c95c21be 100644
--- a/freedreno/freedreno_drmif.h
+++ b/freedreno/freedreno_drmif.h
@@ -61,6 +61,7 @@ enum fd_param_id {
FD_CHIP_ID,
FD_MAX_FREQ,
FD_TIMESTAMP,
+ FD_NR_RINGS, /* # of rings == # of distinct priority levels */
};
/* bo flags: */
@@ -93,6 +94,8 @@ enum fd_version {
FD_VERSION_MADVISE = 1, /* kernel supports madvise */
FD_VERSION_UNLIMITED_CMDS = 1, /* submits w/ >4 cmd buffers (growable ringbuffer) */
FD_VERSION_FENCE_FD = 2, /* submit command supports in/out fences */
+ FD_VERSION_SUBMIT_QUEUES = 3, /* submit queues and multiple priority levels */
+ FD_VERSION_BO_IOVA = 3, /* supports fd_bo_get/put_iova() */
};
enum fd_version fd_device_version(struct fd_device *dev);
@@ -100,6 +103,8 @@ enum fd_version fd_device_version(struct fd_device *dev);
*/
struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id);
+struct fd_pipe * fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio);
+struct fd_pipe * fd_pipe_ref(struct fd_pipe *pipe);
void fd_pipe_del(struct fd_pipe *pipe);
int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
uint64_t *value);
@@ -120,6 +125,8 @@ struct fd_bo *fd_bo_from_handle(struct fd_device *dev,
uint32_t handle, uint32_t size);
struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name);
struct fd_bo * fd_bo_from_dmabuf(struct fd_device *dev, int fd);
+uint64_t fd_bo_get_iova(struct fd_bo *bo);
+void fd_bo_put_iova(struct fd_bo *bo);
struct fd_bo * fd_bo_ref(struct fd_bo *bo);
void fd_bo_del(struct fd_bo *bo);
int fd_bo_get_name(struct fd_bo *bo, uint32_t *name);
diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c
index 3f8c8342..e82e6448 100644
--- a/freedreno/freedreno_pipe.c
+++ b/freedreno/freedreno_pipe.c
@@ -26,60 +26,76 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "freedreno_drmif.h"
#include "freedreno_priv.h"
-struct fd_pipe *
-fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
+/**
+ * priority of zero is highest priority, and higher numeric values are
+ * lower priorities
+ */
+drm_public struct fd_pipe *
+fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio)
{
- struct fd_pipe *pipe = NULL;
+ struct fd_pipe *pipe;
uint64_t val;
if (id > FD_PIPE_MAX) {
ERROR_MSG("invalid pipe id: %d", id);
- goto fail;
+ return NULL;
}
- pipe = dev->funcs->pipe_new(dev, id);
+ if ((prio != 1) && (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)) {
+ ERROR_MSG("invalid priority!");
+ return NULL;
+ }
+
+ pipe = dev->funcs->pipe_new(dev, id, prio);
if (!pipe) {
ERROR_MSG("allocation failed");
- goto fail;
+ return NULL;
}
pipe->dev = dev;
pipe->id = id;
+ atomic_set(&pipe->refcnt, 1);
fd_pipe_get_param(pipe, FD_GPU_ID, &val);
pipe->gpu_id = val;
return pipe;
-fail:
- if (pipe)
- fd_pipe_del(pipe);
- return NULL;
}
-void fd_pipe_del(struct fd_pipe *pipe)
+drm_public struct fd_pipe *
+fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
+{
+ return fd_pipe_new2(dev, id, 1);
+}
+
+drm_public struct fd_pipe * fd_pipe_ref(struct fd_pipe *pipe)
+{
+ atomic_inc(&pipe->refcnt);
+ return pipe;
+}
+
+drm_public void fd_pipe_del(struct fd_pipe *pipe)
{
+ if (!atomic_dec_and_test(&pipe->refcnt))
+ return;
pipe->funcs->destroy(pipe);
}
-int fd_pipe_get_param(struct fd_pipe *pipe,
+drm_public int fd_pipe_get_param(struct fd_pipe *pipe,
enum fd_param_id param, uint64_t *value)
{
return pipe->funcs->get_param(pipe, param, value);
}
-int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
+drm_public int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
{
return fd_pipe_wait_timeout(pipe, timestamp, ~0);
}
-int fd_pipe_wait_timeout(struct fd_pipe *pipe, uint32_t timestamp,
+drm_public int fd_pipe_wait_timeout(struct fd_pipe *pipe, uint32_t timestamp,
uint64_t timeout)
{
return pipe->funcs->wait(pipe, timestamp, timeout);
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index 32170391..b8eac4b2 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -29,10 +29,6 @@
#ifndef FREEDRENO_PRIV_H_
#define FREEDRENO_PRIV_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <errno.h>
#include <string.h>
@@ -49,6 +45,7 @@
#include "xf86atomic.h"
#include "util_double_list.h"
+#include "util_math.h"
#include "freedreno_drmif.h"
#include "freedreno_ringbuffer.h"
@@ -66,7 +63,8 @@ struct fd_device_funcs {
uint32_t flags, uint32_t *handle);
struct fd_bo * (*bo_from_handle)(struct fd_device *dev,
uint32_t size, uint32_t handle);
- struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id);
+ struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id,
+ unsigned prio);
void (*destroy)(struct fd_device *dev);
};
@@ -100,8 +98,12 @@ struct fd_device {
const struct fd_device_funcs *funcs;
struct fd_bo_cache bo_cache;
+ struct fd_bo_cache ring_cache;
int closefd; /* call close(fd) upon destruction */
+
+ /* just for valgrind: */
+ int bo_size;
};
drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse);
@@ -114,7 +116,8 @@ drm_private int fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo);
drm_private void fd_device_del_locked(struct fd_device *dev);
struct fd_pipe_funcs {
- struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size);
+ struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size,
+ enum fd_ringbuffer_flags flags);
int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value);
int (*wait)(struct fd_pipe *pipe, uint32_t timestamp, uint64_t timeout);
void (*destroy)(struct fd_pipe *pipe);
@@ -124,14 +127,10 @@ struct fd_pipe {
struct fd_device *dev;
enum fd_pipe_id id;
uint32_t gpu_id;
+ atomic_t refcnt;
const struct fd_pipe_funcs *funcs;
};
-struct fd_ringmarker {
- struct fd_ringbuffer *ring;
- uint32_t *cur;
-};
-
struct fd_ringbuffer_funcs {
void * (*hostptr)(struct fd_ringbuffer *ring);
int (*flush)(struct fd_ringbuffer *ring, uint32_t *last_start,
@@ -141,8 +140,7 @@ struct fd_ringbuffer_funcs {
void (*emit_reloc)(struct fd_ringbuffer *ring,
const struct fd_reloc *reloc);
uint32_t (*emit_reloc_ring)(struct fd_ringbuffer *ring,
- struct fd_ringbuffer *target, uint32_t cmd_idx,
- uint32_t submit_offset, uint32_t size);
+ struct fd_ringbuffer *target, uint32_t cmd_idx);
uint32_t (*cmd_count)(struct fd_ringbuffer *ring);
void (*destroy)(struct fd_ringbuffer *ring);
};
@@ -152,6 +150,7 @@ struct fd_bo_funcs {
int (*cpu_prep)(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op);
void (*cpu_fini)(struct fd_bo *bo);
int (*madvise)(struct fd_bo *bo, int willneed);
+ uint64_t (*iova)(struct fd_bo *bo);
void (*destroy)(struct fd_bo *bo);
};
@@ -164,12 +163,19 @@ struct fd_bo {
atomic_t refcnt;
const struct fd_bo_funcs *funcs;
- int bo_reuse;
+ enum {
+ NO_CACHE = 0,
+ BO_CACHE = 1,
+ RING_CACHE = 2,
+ } bo_reuse;
+
struct list_head list; /* bucket-list entry */
time_t free_time; /* time when added to bucket-list */
};
-#define ALIGN(v,a) (((v) + (a) - 1) & ~((a) - 1))
+drm_private struct fd_bo *fd_bo_new_ring(struct fd_device *dev,
+ uint32_t size, uint32_t flags);
+
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define enable_debug 0 /* TODO make dynamic */
@@ -196,4 +202,57 @@ offset_bytes(void *end, void *start)
return ((char *)end) - ((char *)start);
}
+#if HAVE_VALGRIND
+# include <memcheck.h>
+
+/*
+ * For tracking the backing memory (if valgrind enabled, we force a mmap
+ * for the purposes of tracking)
+ */
+static inline void VG_BO_ALLOC(struct fd_bo *bo)
+{
+ if (bo && RUNNING_ON_VALGRIND) {
+ VALGRIND_MALLOCLIKE_BLOCK(fd_bo_map(bo), bo->size, 0, 1);
+ }
+}
+
+static inline void VG_BO_FREE(struct fd_bo *bo)
+{
+ VALGRIND_FREELIKE_BLOCK(bo->map, 0);
+}
+
+/*
+ * For tracking bo structs that are in the buffer-cache, so that valgrind
+ * doesn't attribute ownership to the first one to allocate the recycled
+ * bo.
+ *
+ * Note that the list_head in fd_bo is used to track the buffers in cache
+ * so disable error reporting on the range while they are in cache so
+ * valgrind doesn't squawk about list traversal.
+ *
+ */
+static inline void VG_BO_RELEASE(struct fd_bo *bo)
+{
+ if (RUNNING_ON_VALGRIND) {
+ VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size);
+ VALGRIND_MAKE_MEM_NOACCESS(bo, bo->dev->bo_size);
+ VALGRIND_FREELIKE_BLOCK(bo->map, 0);
+ }
+}
+static inline void VG_BO_OBTAIN(struct fd_bo *bo)
+{
+ if (RUNNING_ON_VALGRIND) {
+ VALGRIND_MAKE_MEM_DEFINED(bo, bo->dev->bo_size);
+ VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size);
+ VALGRIND_MALLOCLIKE_BLOCK(bo->map, bo->size, 0, 1);
+ }
+}
+#else
+static inline void VG_BO_ALLOC(struct fd_bo *bo) {}
+static inline void VG_BO_FREE(struct fd_bo *bo) {}
+static inline void VG_BO_RELEASE(struct fd_bo *bo) {}
+static inline void VG_BO_OBTAIN(struct fd_bo *bo) {}
+#endif
+
+
#endif /* FREEDRENO_PRIV_H_ */
diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c
index 7310f1fd..8f0093ae 100644
--- a/freedreno/freedreno_ringbuffer.c
+++ b/freedreno/freedreno_ringbuffer.c
@@ -26,25 +26,30 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <assert.h>
#include "freedreno_drmif.h"
#include "freedreno_priv.h"
#include "freedreno_ringbuffer.h"
-struct fd_ringbuffer *
-fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
+drm_public struct fd_ringbuffer *
+fd_ringbuffer_new_flags(struct fd_pipe *pipe, uint32_t size,
+ enum fd_ringbuffer_flags flags)
{
struct fd_ringbuffer *ring;
- ring = pipe->funcs->ringbuffer_new(pipe, size);
+ /* we can't really support "growable" rb's in general for
+ * stateobj's since we need a single gpu addr (ie. can't
+ * do the trick of a chain of IB packets):
+ */
+ if (flags & FD_RINGBUFFER_OBJECT)
+ assert(size);
+
+ ring = pipe->funcs->ringbuffer_new(pipe, size, flags);
if (!ring)
return NULL;
+ ring->flags = flags;
ring->pipe = pipe;
ring->start = ring->funcs->hostptr(ring);
ring->end = &(ring->start[ring->size/4]);
@@ -54,23 +59,48 @@ fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
return ring;
}
-void fd_ringbuffer_del(struct fd_ringbuffer *ring)
+drm_public struct fd_ringbuffer *
+fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
+{
+ return fd_ringbuffer_new_flags(pipe, size, 0);
+}
+
+drm_public struct fd_ringbuffer *
+fd_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size)
+{
+ return fd_ringbuffer_new_flags(pipe, size, FD_RINGBUFFER_OBJECT);
+}
+
+drm_public void fd_ringbuffer_del(struct fd_ringbuffer *ring)
{
+ if (!atomic_dec_and_test(&ring->refcnt))
+ return;
+
fd_ringbuffer_reset(ring);
ring->funcs->destroy(ring);
}
+drm_public struct fd_ringbuffer *
+fd_ringbuffer_ref(struct fd_ringbuffer *ring)
+{
+ STATIC_ASSERT(sizeof(ring->refcnt) <= sizeof(ring->__pad));
+ atomic_inc(&ring->refcnt);
+ return ring;
+}
+
/* ringbuffers which are IB targets should set the toplevel rb (ie.
* the IB source) as it's parent before emitting reloc's, to ensure
* the bookkeeping works out properly.
*/
-void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
+drm_public void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
struct fd_ringbuffer *parent)
{
+ /* state objects should not be parented! */
+ assert(!(ring->flags & FD_RINGBUFFER_OBJECT));
ring->parent = parent;
}
-void fd_ringbuffer_reset(struct fd_ringbuffer *ring)
+drm_public void fd_ringbuffer_reset(struct fd_ringbuffer *ring)
{
uint32_t *start = ring->start;
if (ring->pipe->id == FD_PIPE_2D)
@@ -80,18 +110,18 @@ void fd_ringbuffer_reset(struct fd_ringbuffer *ring)
ring->funcs->reset(ring);
}
-int fd_ringbuffer_flush(struct fd_ringbuffer *ring)
+drm_public int fd_ringbuffer_flush(struct fd_ringbuffer *ring)
{
return ring->funcs->flush(ring, ring->last_start, -1, NULL);
}
-int fd_ringbuffer_flush2(struct fd_ringbuffer *ring, int in_fence_fd,
+drm_public int fd_ringbuffer_flush2(struct fd_ringbuffer *ring, int in_fence_fd,
int *out_fence_fd)
{
return ring->funcs->flush(ring, ring->last_start, in_fence_fd, out_fence_fd);
}
-void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords)
+drm_public void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords)
{
assert(ring->funcs->grow); /* unsupported on kgsl */
@@ -107,89 +137,46 @@ void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords)
ring->cur = ring->last_start = ring->start;
}
-uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring)
+drm_public uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring)
{
return ring->last_timestamp;
}
-void fd_ringbuffer_reloc(struct fd_ringbuffer *ring,
+drm_public void fd_ringbuffer_reloc(struct fd_ringbuffer *ring,
const struct fd_reloc *reloc)
{
assert(ring->pipe->gpu_id < 500);
ring->funcs->emit_reloc(ring, reloc);
}
-void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring,
+drm_public void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring,
const struct fd_reloc *reloc)
{
ring->funcs->emit_reloc(ring, reloc);
}
-void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
- struct fd_ringmarker *target, struct fd_ringmarker *end)
-{
- uint32_t submit_offset, size;
-
- /* This function is deprecated and not supported on 64b devices: */
- assert(ring->pipe->gpu_id < 500);
- assert(target->ring == end->ring);
-
- submit_offset = offset_bytes(target->cur, target->ring->start);
- size = offset_bytes(end->cur, target->cur);
-
- ring->funcs->emit_reloc_ring(ring, target->ring, 0, submit_offset, size);
-}
-
-uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring)
+drm_public uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring)
{
if (!ring->funcs->cmd_count)
return 1;
return ring->funcs->cmd_count(ring);
}
-uint32_t
+drm_public uint32_t
fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring,
struct fd_ringbuffer *target, uint32_t cmd_idx)
{
- uint32_t size = offset_bytes(target->cur, target->start);
- return ring->funcs->emit_reloc_ring(ring, target, cmd_idx, 0, size);
+ return ring->funcs->emit_reloc_ring(ring, target, cmd_idx);
}
-struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring)
+drm_public uint32_t
+fd_ringbuffer_size(struct fd_ringbuffer *ring)
{
- struct fd_ringmarker *marker = NULL;
-
- marker = calloc(1, sizeof(*marker));
- if (!marker) {
- ERROR_MSG("allocation failed");
- return NULL;
- }
-
- marker->ring = ring;
-
- marker->cur = marker->ring->cur;
-
- return marker;
+ /* only really needed for stateobj ringbuffers, and won't really
+ * do what you expect for growable rb's.. so lets just restrict
+ * this to stateobj's for now:
+ */
+ assert(ring->flags & FD_RINGBUFFER_OBJECT);
+ return offset_bytes(ring->cur, ring->start);
}
-void fd_ringmarker_del(struct fd_ringmarker *marker)
-{
- free(marker);
-}
-
-void fd_ringmarker_mark(struct fd_ringmarker *marker)
-{
- marker->cur = marker->ring->cur;
-}
-
-uint32_t fd_ringmarker_dwords(struct fd_ringmarker *start,
- struct fd_ringmarker *end)
-{
- return end->cur - start->cur;
-}
-
-int fd_ringmarker_flush(struct fd_ringmarker *marker)
-{
- struct fd_ringbuffer *ring = marker->ring;
- return ring->funcs->flush(ring, marker->cur, -1, NULL);
-}
diff --git a/freedreno/freedreno_ringbuffer.h b/freedreno/freedreno_ringbuffer.h
index c501fbad..bc41a31c 100644
--- a/freedreno/freedreno_ringbuffer.h
+++ b/freedreno/freedreno_ringbuffer.h
@@ -33,12 +33,33 @@
/* the ringbuffer object is not opaque so that OUT_RING() type stuff
* can be inlined. Note that users should not make assumptions about
- * the size of this struct.. more stuff will be added when we eventually
- * have a kernel driver that can deal w/ reloc's..
+ * the size of this struct.
*/
struct fd_ringbuffer_funcs;
-struct fd_ringmarker;
+
+enum fd_ringbuffer_flags {
+
+ /* Ringbuffer is a "state object", which is potentially reused
+ * many times, rather than being used in one-shot mode linked
+ * to a parent ringbuffer.
+ */
+ FD_RINGBUFFER_OBJECT = 0x1,
+
+ /* Hint that the stateobj will be used for streaming state
+ * that is used once or a few times and then discarded.
+ *
+ * For sub-allocation, non streaming stateobj's should be
+ * sub-allocated from a page size buffer, so one long lived
+ * state obj doesn't prevent other pages from being freed.
+ * (Ie. it would be no worse than allocating a page sized
+ * bo for each small non-streaming stateobj).
+ *
+ * But streaming stateobj's could be sub-allocated from a
+ * larger buffer to reduce the alloc/del overhead.
+ */
+ FD_RINGBUFFER_STREAMING = 0x2,
+};
struct fd_ringbuffer {
int size;
@@ -47,13 +68,41 @@ struct fd_ringbuffer {
const struct fd_ringbuffer_funcs *funcs;
uint32_t last_timestamp;
struct fd_ringbuffer *parent;
+
+ /* for users of fd_ringbuffer to store their own private per-
+ * ringbuffer data
+ */
+ void *user;
+
+ enum fd_ringbuffer_flags flags;
+
+ /* This is a bit gross, but we can't use atomic_t in exported
+ * headers. OTOH, we don't need the refcnt to be publicly
+ * visible. The only reason that this struct is exported is
+ * because fd_ringbuffer_emit needs to be something that can
+ * be inlined for performance reasons.
+ */
+ union {
+#ifdef HAS_ATOMIC_OPS
+ atomic_t refcnt;
+#endif
+ uint64_t __pad;
+ };
};
struct fd_ringbuffer * fd_ringbuffer_new(struct fd_pipe *pipe,
uint32_t size);
+will_be_deprecated
+struct fd_ringbuffer * fd_ringbuffer_new_object(struct fd_pipe *pipe,
+ uint32_t size);
+struct fd_ringbuffer * fd_ringbuffer_new_flags(struct fd_pipe *pipe,
+ uint32_t size, enum fd_ringbuffer_flags flags);
+
+struct fd_ringbuffer *fd_ringbuffer_ref(struct fd_ringbuffer *ring);
void fd_ringbuffer_del(struct fd_ringbuffer *ring);
void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
struct fd_ringbuffer *parent);
+will_be_deprecated
void fd_ringbuffer_reset(struct fd_ringbuffer *ring);
int fd_ringbuffer_flush(struct fd_ringbuffer *ring);
/* in_fence_fd: -1 for no in-fence, else fence fd
@@ -85,17 +134,9 @@ struct fd_reloc {
void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring, const struct fd_reloc *reloc);
will_be_deprecated void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, const struct fd_reloc *reloc);
-will_be_deprecated void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
- struct fd_ringmarker *target, struct fd_ringmarker *end);
uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring);
uint32_t fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring,
struct fd_ringbuffer *target, uint32_t cmd_idx);
-
-will_be_deprecated struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring);
-will_be_deprecated void fd_ringmarker_del(struct fd_ringmarker *marker);
-will_be_deprecated void fd_ringmarker_mark(struct fd_ringmarker *marker);
-will_be_deprecated uint32_t fd_ringmarker_dwords(struct fd_ringmarker *start,
- struct fd_ringmarker *end);
-will_be_deprecated int fd_ringmarker_flush(struct fd_ringmarker *marker);
+uint32_t fd_ringbuffer_size(struct fd_ringbuffer *ring);
#endif /* FREEDRENO_RINGBUFFER_H_ */
diff --git a/freedreno/kgsl/kgsl_bo.c b/freedreno/kgsl/kgsl_bo.c
index ab3485e3..7a6af2f0 100644
--- a/freedreno/kgsl/kgsl_bo.c
+++ b/freedreno/kgsl/kgsl_bo.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "kgsl_priv.h"
#include <linux/fb.h>
@@ -181,7 +177,7 @@ drm_private struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev,
return bo;
}
-struct fd_bo *
+drm_public struct fd_bo *
fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size)
{
struct fd_bo *bo;
diff --git a/freedreno/kgsl/kgsl_device.c b/freedreno/kgsl/kgsl_device.c
index 175e8378..914f3412 100644
--- a/freedreno/kgsl/kgsl_device.c
+++ b/freedreno/kgsl/kgsl_device.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -61,5 +57,7 @@ drm_private struct fd_device * kgsl_device_new(int fd)
dev = &kgsl_dev->base;
dev->funcs = &funcs;
+ dev->bo_size = sizeof(struct kgsl_bo);
+
return dev;
}
diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c
index 8a39eb49..0a8b6586 100644
--- a/freedreno/kgsl/kgsl_pipe.c
+++ b/freedreno/kgsl/kgsl_pipe.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "kgsl_priv.h"
@@ -52,6 +48,7 @@ static int kgsl_pipe_get_param(struct fd_pipe *pipe,
return 0;
case FD_MAX_FREQ:
case FD_TIMESTAMP:
+ case FD_NR_RINGS:
/* unsupported on kgsl */
return -1;
default:
@@ -210,7 +207,7 @@ static int getprop(int fd, enum kgsl_property_type type,
drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
- enum fd_pipe_id id)
+ enum fd_pipe_id id, uint32_t prio)
{
static const char *paths[] = {
[FD_PIPE_3D] = "/dev/kgsl-3d0",
diff --git a/freedreno/kgsl/kgsl_priv.h b/freedreno/kgsl/kgsl_priv.h
index 6ab64965..a6bf2d40 100644
--- a/freedreno/kgsl/kgsl_priv.h
+++ b/freedreno/kgsl/kgsl_priv.h
@@ -103,10 +103,10 @@ drm_private void kgsl_pipe_post_submit(struct kgsl_pipe *pipe,
drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe,
uint32_t timestamp);
drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
- enum fd_pipe_id id);
+ enum fd_pipe_id id, uint32_t prio);
drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
- uint32_t size);
+ uint32_t size, enum fd_ringbuffer_flags flags);
drm_private int kgsl_bo_new_handle(struct fd_device *dev,
uint32_t size, uint32_t flags, uint32_t *handle);
diff --git a/freedreno/kgsl/kgsl_ringbuffer.c b/freedreno/kgsl/kgsl_ringbuffer.c
index e4696b1b..9abf0adf 100644
--- a/freedreno/kgsl/kgsl_ringbuffer.c
+++ b/freedreno/kgsl/kgsl_ringbuffer.c
@@ -26,12 +26,9 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <assert.h>
+#include "xf86atomic.h"
#include "freedreno_ringbuffer.h"
#include "kgsl_priv.h"
@@ -146,7 +143,7 @@ static int kgsl_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_star
ibdesc.gpuaddr = kgsl_ring->bo->gpuaddr;
ibdesc.hostptr = kgsl_ring->bo->hostptr;
ibdesc.sizedwords = 0x145;
- req.timestamp = (uint32_t)kgsl_ring->bo->hostptr;
+ req.timestamp = (uintptr_t)kgsl_ring->bo->hostptr;
}
do {
@@ -178,13 +175,12 @@ static void kgsl_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
}
static uint32_t kgsl_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
- struct fd_ringbuffer *target, uint32_t cmd_idx,
- uint32_t submit_offset, uint32_t size)
+ struct fd_ringbuffer *target, uint32_t cmd_idx)
{
struct kgsl_ringbuffer *target_ring = to_kgsl_ringbuffer(target);
assert(cmd_idx == 0);
- (*ring->cur++) = target_ring->bo->gpuaddr + submit_offset;
- return size;
+ (*ring->cur++) = target_ring->bo->gpuaddr;
+ return offset_bytes(target->cur, target->start);
}
static void kgsl_ringbuffer_destroy(struct fd_ringbuffer *ring)
@@ -206,11 +202,13 @@ static const struct fd_ringbuffer_funcs funcs = {
};
drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
- uint32_t size)
+ uint32_t size, enum fd_ringbuffer_flags flags)
{
struct kgsl_ringbuffer *kgsl_ring;
struct fd_ringbuffer *ring = NULL;
+ assert(!flags);
+
kgsl_ring = calloc(1, sizeof(*kgsl_ring));
if (!kgsl_ring) {
ERROR_MSG("allocation failed");
@@ -218,6 +216,8 @@ drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
}
ring = &kgsl_ring->base;
+ atomic_set(&ring->refcnt, 1);
+
ring->funcs = &funcs;
ring->size = size;
diff --git a/freedreno/meson.build b/freedreno/meson.build
new file mode 100644
index 00000000..c9aba060
--- /dev/null
+++ b/freedreno/meson.build
@@ -0,0 +1,77 @@
+# 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.
+
+files_freedreno = files(
+ 'freedreno_device.c',
+ 'freedreno_pipe.c',
+ 'freedreno_ringbuffer.c',
+ 'freedreno_bo.c',
+ 'freedreno_bo_cache.c',
+ 'msm/msm_bo.c',
+ 'msm/msm_device.c',
+ 'msm/msm_pipe.c',
+ 'msm/msm_ringbuffer.c',
+)
+
+if with_freedreno_kgsl
+ files_freedreno += files(
+ 'kgsl/kgsl_bo.c',
+ 'kgsl/kgsl_device.c',
+ 'kgsl/kgsl_pipe.c',
+ 'kgsl/kgsl_ringbuffer.c',
+ )
+endif
+
+libdrm_freedreno = shared_library(
+ 'drm_freedreno',
+ [files_freedreno, config_file],
+ c_args : libdrm_c_args,
+ include_directories : [inc_root, inc_drm],
+ dependencies : [dep_valgrind, dep_pthread_stubs, dep_rt, dep_atomic_ops],
+ link_with : libdrm,
+ version : '1.0.0',
+ install : true,
+)
+
+ext_libdrm_freedreno = declare_dependency(
+ link_with : [libdrm, libdrm_freedreno],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+install_headers(
+ 'freedreno_drmif.h', 'freedreno_ringbuffer.h',
+ subdir : 'freedreno'
+)
+
+pkg.generate(
+ name : 'libdrm_freedreno',
+ libraries : libdrm_freedreno,
+ subdirs : ['.', 'libdrm', 'freedreno'],
+ version : meson.project_version(),
+ requires_private : 'libdrm',
+ description : 'Userspace interface to freedreno kernel DRM services',
+)
+
+test(
+ 'freedreno-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('freedreno-symbol-check'), libdrm_freedreno]
+)
diff --git a/freedreno/msm/msm_bo.c b/freedreno/msm/msm_bo.c
index 72471df6..8b3d0bcb 100644
--- a/freedreno/msm/msm_bo.c
+++ b/freedreno/msm/msm_bo.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "msm_priv.h"
static int bo_allocate(struct msm_bo *msm_bo)
@@ -108,6 +104,18 @@ static int msm_bo_madvise(struct fd_bo *bo, int willneed)
return req.retained;
}
+static uint64_t msm_bo_iova(struct fd_bo *bo)
+{
+ struct drm_msm_gem_info req = {
+ .handle = bo->handle,
+ .flags = MSM_INFO_IOVA,
+ };
+
+ drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req));
+
+ return req.offset;
+}
+
static void msm_bo_destroy(struct fd_bo *bo)
{
struct msm_bo *msm_bo = to_msm_bo(bo);
@@ -120,6 +128,7 @@ static const struct fd_bo_funcs funcs = {
.cpu_prep = msm_bo_cpu_prep,
.cpu_fini = msm_bo_cpu_fini,
.madvise = msm_bo_madvise,
+ .iova = msm_bo_iova,
.destroy = msm_bo_destroy,
};
diff --git a/freedreno/msm/msm_device.c b/freedreno/msm/msm_device.c
index 727baa44..58b0746d 100644
--- a/freedreno/msm/msm_device.c
+++ b/freedreno/msm/msm_device.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -39,7 +35,6 @@
static void msm_device_destroy(struct fd_device *dev)
{
struct msm_device *msm_dev = to_msm_device(dev);
- fd_bo_cache_cleanup(&msm_dev->ring_cache, 0);
free(msm_dev);
}
@@ -62,7 +57,7 @@ drm_private struct fd_device * msm_device_new(int fd)
dev = &msm_dev->base;
dev->funcs = &funcs;
- fd_bo_cache_init(&msm_dev->ring_cache, TRUE);
+ dev->bo_size = sizeof(struct msm_bo);
return dev;
}
diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c
index f872e245..e070b317 100644
--- a/freedreno/msm/msm_pipe.c
+++ b/freedreno/msm/msm_pipe.c
@@ -26,10 +26,6 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "msm_priv.h"
static int query_param(struct fd_pipe *pipe, uint32_t param,
@@ -71,6 +67,8 @@ static int msm_pipe_get_param(struct fd_pipe *pipe,
return query_param(pipe, MSM_PARAM_MAX_FREQ, value);
case FD_TIMESTAMP:
return query_param(pipe, MSM_PARAM_TIMESTAMP, value);
+ case FD_NR_RINGS:
+ return query_param(pipe, MSM_PARAM_NR_RINGS, value);
default:
ERROR_MSG("invalid param id: %d", param);
return -1;
@@ -83,6 +81,7 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
struct fd_device *dev = pipe->dev;
struct drm_msm_wait_fence req = {
.fence = timestamp,
+ .queueid = to_msm_pipe(pipe)->queue_id,
};
int ret;
@@ -97,9 +96,54 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
return 0;
}
+static int open_submitqueue(struct fd_pipe *pipe, uint32_t prio)
+{
+ struct drm_msm_submitqueue req = {
+ .flags = 0,
+ .prio = prio,
+ };
+ uint64_t nr_rings = 1;
+ int ret;
+
+ if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) {
+ to_msm_pipe(pipe)->queue_id = 0;
+ return 0;
+ }
+
+ msm_pipe_get_param(pipe, FD_NR_RINGS, &nr_rings);
+
+ req.prio = MIN2(req.prio, MAX2(nr_rings, 1) - 1);
+
+ ret = drmCommandWriteRead(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_NEW,
+ &req, sizeof(req));
+ if (ret) {
+ ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno));
+ return ret;
+ }
+
+ to_msm_pipe(pipe)->queue_id = req.id;
+ return 0;
+}
+
+static void close_submitqueue(struct fd_pipe *pipe, uint32_t queue_id)
+{
+ if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES)
+ return;
+
+ drmCommandWrite(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE,
+ &queue_id, sizeof(queue_id));
+}
+
static void msm_pipe_destroy(struct fd_pipe *pipe)
{
struct msm_pipe *msm_pipe = to_msm_pipe(pipe);
+ close_submitqueue(pipe, msm_pipe->queue_id);
+
+ if (msm_pipe->suballoc_ring) {
+ fd_ringbuffer_del(msm_pipe->suballoc_ring);
+ msm_pipe->suballoc_ring = NULL;
+ }
+
free(msm_pipe);
}
@@ -122,7 +166,7 @@ static uint64_t get_param(struct fd_pipe *pipe, uint32_t param)
}
drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
- enum fd_pipe_id id)
+ enum fd_pipe_id id, uint32_t prio)
{
static const uint32_t pipe_id[] = {
[FD_PIPE_3D] = MSM_PIPE_3D0,
@@ -157,6 +201,9 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id);
INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem);
+ if (open_submitqueue(pipe, prio))
+ goto fail;
+
return pipe;
fail:
if (pipe)
diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h
index 6d670aab..cc951fba 100644
--- a/freedreno/msm/msm_priv.h
+++ b/freedreno/msm/msm_priv.h
@@ -56,6 +56,18 @@ struct msm_pipe {
uint32_t gpu_id;
uint32_t gmem;
uint32_t chip_id;
+ uint32_t queue_id;
+
+ /* Allow for sub-allocation of stateobj ring buffers (ie. sharing
+ * the same underlying bo)..
+ *
+ * This takes advantage of each context having it's own fd_pipe,
+ * so we don't have to worry about access from multiple threads.
+ *
+ * We also rely on previous stateobj having been fully constructed
+ * so we can reclaim extra space at it's end.
+ */
+ struct fd_ringbuffer *suballoc_ring;
};
static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x)
@@ -64,10 +76,10 @@ static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x)
}
drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
- enum fd_pipe_id id);
+ enum fd_pipe_id id, uint32_t prio);
drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
- uint32_t size);
+ uint32_t size, enum fd_ringbuffer_flags flags);
struct msm_bo {
struct fd_bo base;
@@ -100,4 +112,30 @@ static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns)
tv->tv_nsec = t.tv_nsec + ns - (s * 1000000000);
}
+/*
+ * Stupid/simple growable array implementation:
+ */
+
+static inline void *
+grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz)
+{
+ if ((nr + 1) > *max) {
+ if ((*max * 2) < (nr + 1))
+ *max = nr + 5;
+ else
+ *max = *max * 2;
+ ptr = realloc(ptr, *max * sz);
+ }
+ return ptr;
+}
+
+#define DECLARE_ARRAY(type, name) \
+ unsigned nr_ ## name, max_ ## name; \
+ type * name;
+
+#define APPEND(x, name) ({ \
+ (x)->name = grow((x)->name, (x)->nr_ ## name, &(x)->max_ ## name, sizeof((x)->name[0])); \
+ (x)->nr_ ## name ++; \
+})
+
#endif /* MSM_PRIV_H_ */
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index 17194f4c..475c65d7 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -26,13 +26,10 @@
* Rob Clark <robclark@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <assert.h>
#include <inttypes.h>
+#include "xf86atomic.h"
#include "freedreno_ringbuffer.h"
#include "msm_priv.h"
@@ -46,10 +43,12 @@ struct msm_cmd {
struct fd_bo *ring_bo;
/* reloc's table: */
- struct drm_msm_gem_submit_reloc *relocs;
- uint32_t nr_relocs, max_relocs;
+ DECLARE_ARRAY(struct drm_msm_gem_submit_reloc, relocs);
uint32_t size;
+
+ /* has cmd already been added to parent rb's submit.cmds table? */
+ int is_appended_to_submit;
};
struct msm_ringbuffer {
@@ -62,22 +61,18 @@ struct msm_ringbuffer {
*/
struct {
/* bo's table: */
- struct drm_msm_gem_submit_bo *bos;
- uint32_t nr_bos, max_bos;
+ DECLARE_ARRAY(struct drm_msm_gem_submit_bo, bos);
/* cmd's table: */
- struct drm_msm_gem_submit_cmd *cmds;
- uint32_t nr_cmds, max_cmds;
+ DECLARE_ARRAY(struct drm_msm_gem_submit_cmd, cmds);
} submit;
/* should have matching entries in submit.bos: */
/* Note, only in parent ringbuffer */
- struct fd_bo **bos;
- uint32_t nr_bos, max_bos;
+ DECLARE_ARRAY(struct fd_bo *, bos);
/* should have matching entries in submit.cmds: */
- struct msm_cmd **cmds;
- uint32_t nr_cmds, max_cmds;
+ DECLARE_ARRAY(struct msm_cmd *, cmds);
/* List of physical cmdstream buffers (msm_cmd) assocated with this
* logical fd_ringbuffer.
@@ -93,10 +88,24 @@ struct msm_ringbuffer {
int is_growable;
unsigned cmd_count;
+ unsigned offset; /* for sub-allocated stateobj rb's */
+
unsigned seqno;
/* maps fd_bo to idx: */
void *bo_table;
+
+ /* maps msm_cmd to drm_msm_gem_submit_cmd in parent rb. Each rb has a
+ * list of msm_cmd's which correspond to each chunk of cmdstream in
+ * a 'growable' rb. For each of those we need to create one
+ * drm_msm_gem_submit_cmd in the parent rb which collects the state
+ * for the submit ioctl. Because we can have multiple IB's to the same
+ * target rb (for example, or same stateobj emit multiple times), and
+ * because in theory we can have multiple different rb's that have a
+ * reference to a given target, we need a hashtable to track this per
+ * rb.
+ */
+ void *cmd_table;
};
static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x)
@@ -107,51 +116,25 @@ static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x)
#define INIT_SIZE 0x1000
static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER;
-drm_private extern pthread_mutex_t table_lock;
-
-static void ring_bo_del(struct fd_device *dev, struct fd_bo *bo)
-{
- int ret;
-
- pthread_mutex_lock(&table_lock);
- ret = fd_bo_cache_free(&to_msm_device(dev)->ring_cache, bo);
- pthread_mutex_unlock(&table_lock);
- if (ret == 0)
- return;
-
- fd_bo_del(bo);
-}
-
-static struct fd_bo * ring_bo_new(struct fd_device *dev, uint32_t size)
+static struct msm_cmd *current_cmd(struct fd_ringbuffer *ring)
{
- struct fd_bo *bo;
-
- bo = fd_bo_cache_alloc(&to_msm_device(dev)->ring_cache, &size, 0);
- if (bo)
- return bo;
-
- bo = fd_bo_new(dev, size, 0);
- if (!bo)
- return NULL;
-
- /* keep ringbuffer bo's out of the normal bo cache: */
- bo->bo_reuse = FALSE;
-
- return bo;
+ struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
+ assert(!LIST_IS_EMPTY(&msm_ring->cmd_list));
+ return LIST_LAST_ENTRY(&msm_ring->cmd_list, struct msm_cmd, list);
}
static void ring_cmd_del(struct msm_cmd *cmd)
{
- if (cmd->ring_bo)
- ring_bo_del(cmd->ring->pipe->dev, cmd->ring_bo);
+ fd_bo_del(cmd->ring_bo);
list_del(&cmd->list);
to_msm_ringbuffer(cmd->ring)->cmd_count--;
free(cmd->relocs);
free(cmd);
}
-static struct msm_cmd * ring_cmd_new(struct fd_ringbuffer *ring, uint32_t size)
+static struct msm_cmd * ring_cmd_new(struct fd_ringbuffer *ring, uint32_t size,
+ enum fd_ringbuffer_flags flags)
{
struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
struct msm_cmd *cmd = calloc(1, sizeof(*cmd));
@@ -160,7 +143,48 @@ static struct msm_cmd * ring_cmd_new(struct fd_ringbuffer *ring, uint32_t size)
return NULL;
cmd->ring = ring;
- cmd->ring_bo = ring_bo_new(ring->pipe->dev, size);
+
+ /* TODO separate suballoc buffer for small non-streaming state, using
+ * smaller page-sized backing bo's.
+ */
+ if (flags & FD_RINGBUFFER_STREAMING) {
+ struct msm_pipe *msm_pipe = to_msm_pipe(ring->pipe);
+ unsigned suballoc_offset = 0;
+ struct fd_bo *suballoc_bo = NULL;
+
+ if (msm_pipe->suballoc_ring) {
+ struct msm_ringbuffer *suballoc_ring = to_msm_ringbuffer(msm_pipe->suballoc_ring);
+
+ assert(msm_pipe->suballoc_ring->flags & FD_RINGBUFFER_OBJECT);
+ assert(suballoc_ring->cmd_count == 1);
+
+ suballoc_bo = current_cmd(msm_pipe->suballoc_ring)->ring_bo;
+
+ suballoc_offset = fd_ringbuffer_size(msm_pipe->suballoc_ring) +
+ suballoc_ring->offset;
+
+ suballoc_offset = ALIGN(suballoc_offset, 0x10);
+
+ if ((size + suballoc_offset) > suballoc_bo->size) {
+ suballoc_bo = NULL;
+ }
+ }
+
+ if (!suballoc_bo) {
+ cmd->ring_bo = fd_bo_new_ring(ring->pipe->dev, 0x8000, 0);
+ msm_ring->offset = 0;
+ } else {
+ cmd->ring_bo = fd_bo_ref(suballoc_bo);
+ msm_ring->offset = suballoc_offset;
+ }
+
+ if (msm_pipe->suballoc_ring)
+ fd_ringbuffer_del(msm_pipe->suballoc_ring);
+
+ msm_pipe->suballoc_ring = fd_ringbuffer_ref(ring);
+ } else {
+ cmd->ring_bo = fd_bo_new_ring(ring->pipe->dev, size, 0);
+ }
if (!cmd->ring_bo)
goto fail;
@@ -174,30 +198,6 @@ fail:
return NULL;
}
-static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz)
-{
- if ((nr + 1) > *max) {
- if ((*max * 2) < (nr + 1))
- *max = nr + 5;
- else
- *max = *max * 2;
- ptr = realloc(ptr, *max * sz);
- }
- return ptr;
-}
-
-#define APPEND(x, name) ({ \
- (x)->name = grow((x)->name, (x)->nr_ ## name, &(x)->max_ ## name, sizeof((x)->name[0])); \
- (x)->nr_ ## name ++; \
-})
-
-static struct msm_cmd *current_cmd(struct fd_ringbuffer *ring)
-{
- struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
- assert(!LIST_IS_EMPTY(&msm_ring->cmd_list));
- return LIST_LAST_ENTRY(&msm_ring->cmd_list, struct msm_cmd, list);
-}
-
static uint32_t append_bo(struct fd_ringbuffer *ring, struct fd_bo *bo)
{
struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
@@ -249,31 +249,43 @@ static uint32_t bo2idx(struct fd_ringbuffer *ring, struct fd_bo *bo, uint32_t fl
return idx;
}
-static int check_cmd_bo(struct fd_ringbuffer *ring,
- struct drm_msm_gem_submit_cmd *cmd, struct fd_bo *bo)
-{
- struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
- return msm_ring->submit.bos[cmd->submit_idx].handle == bo->handle;
-}
-
/* Ensure that submit has corresponding entry in cmds table for the
* target cmdstream buffer:
+ *
+ * Returns TRUE if new cmd added (else FALSE if it was already in
+ * the cmds table)
*/
-static void get_cmd(struct fd_ringbuffer *ring, struct msm_cmd *target_cmd,
+static int get_cmd(struct fd_ringbuffer *ring, struct msm_cmd *target_cmd,
uint32_t submit_offset, uint32_t size, uint32_t type)
{
struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
struct drm_msm_gem_submit_cmd *cmd;
uint32_t i;
+ void *val;
- /* figure out if we already have a cmd buf: */
- for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
+ if (!msm_ring->cmd_table)
+ msm_ring->cmd_table = drmHashCreate();
+
+ /* figure out if we already have a cmd buf.. short-circuit hash
+ * lookup if:
+ * - target cmd has never been added to submit.cmds
+ * - target cmd is not a streaming stateobj (which unlike longer
+ * lived CSO stateobj, is not expected to be reused with multiple
+ * submits)
+ */
+ if (target_cmd->is_appended_to_submit &&
+ !(target_cmd->ring->flags & FD_RINGBUFFER_STREAMING) &&
+ !drmHashLookup(msm_ring->cmd_table, (unsigned long)target_cmd, &val)) {
+ i = VOID2U64(val);
cmd = &msm_ring->submit.cmds[i];
- if ((cmd->submit_offset == submit_offset) &&
- (cmd->size == size) &&
- (cmd->type == type) &&
- check_cmd_bo(ring, cmd, target_cmd->ring_bo))
- return;
+
+ assert(cmd->submit_offset == submit_offset);
+ assert(cmd->size == size);
+ assert(cmd->type == type);
+ assert(msm_ring->submit.bos[cmd->submit_idx].handle ==
+ target_cmd->ring_bo->handle);
+
+ return FALSE;
}
/* create cmd buf if not: */
@@ -287,27 +299,23 @@ static void get_cmd(struct fd_ringbuffer *ring, struct msm_cmd *target_cmd,
cmd->size = size;
cmd->pad = 0;
+ target_cmd->is_appended_to_submit = TRUE;
+
+ if (!(target_cmd->ring->flags & FD_RINGBUFFER_STREAMING)) {
+ drmHashInsert(msm_ring->cmd_table, (unsigned long)target_cmd,
+ U642VOID(i));
+ }
+
target_cmd->size = size;
-}
-static void * msm_ringbuffer_hostptr(struct fd_ringbuffer *ring)
-{
- return fd_bo_map(current_cmd(ring)->ring_bo);
+ return TRUE;
}
-static uint32_t find_next_reloc_idx(struct msm_cmd *msm_cmd,
- uint32_t start, uint32_t offset)
+static void * msm_ringbuffer_hostptr(struct fd_ringbuffer *ring)
{
- uint32_t i;
-
- /* a binary search would be more clever.. */
- for (i = start; i < msm_cmd->nr_relocs; i++) {
- struct drm_msm_gem_submit_reloc *reloc = &msm_cmd->relocs[i];
- if (reloc->submit_offset >= offset)
- return i;
- }
-
- return i;
+ struct msm_cmd *cmd = current_cmd(ring);
+ uint8_t *base = fd_bo_map(cmd->ring_bo);
+ return base + to_msm_ringbuffer(ring)->offset;
}
static void delete_cmds(struct msm_ringbuffer *msm_ring)
@@ -326,14 +334,20 @@ static void flush_reset(struct fd_ringbuffer *ring)
for (i = 0; i < msm_ring->nr_bos; i++) {
struct msm_bo *msm_bo = to_msm_bo(msm_ring->bos[i]);
+ if (!msm_bo)
+ continue;
msm_bo->current_ring_seqno = 0;
fd_bo_del(&msm_bo->base);
}
- /* for each of the cmd buffers, clear their reloc's: */
- for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
- struct msm_cmd *target_cmd = msm_ring->cmds[i];
- target_cmd->nr_relocs = 0;
+ for (i = 0; i < msm_ring->nr_cmds; i++) {
+ struct msm_cmd *msm_cmd = msm_ring->cmds[i];
+
+ if (msm_cmd->ring == ring)
+ continue;
+
+ if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT)
+ fd_ringbuffer_del(msm_cmd->ring);
}
msm_ring->submit.nr_cmds = 0;
@@ -346,6 +360,11 @@ static void flush_reset(struct fd_ringbuffer *ring)
msm_ring->bo_table = NULL;
}
+ if (msm_ring->cmd_table) {
+ drmHashDestroy(msm_ring->cmd_table);
+ msm_ring->cmd_table = NULL;
+ }
+
if (msm_ring->is_growable) {
delete_cmds(msm_ring);
} else {
@@ -395,16 +414,63 @@ static void dump_submit(struct msm_ringbuffer *msm_ring)
}
}
+static struct drm_msm_gem_submit_reloc *
+handle_stateobj_relocs(struct fd_ringbuffer *parent, struct fd_ringbuffer *stateobj,
+ struct drm_msm_gem_submit_reloc *orig_relocs, unsigned nr_relocs)
+{
+ struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(stateobj);
+ struct drm_msm_gem_submit_reloc *relocs = malloc(nr_relocs * sizeof(*relocs));
+ unsigned i;
+
+ for (i = 0; i < nr_relocs; i++) {
+ unsigned idx = orig_relocs[i].reloc_idx;
+ struct fd_bo *bo = msm_ring->bos[idx];
+ unsigned flags = 0;
+
+ if (msm_ring->submit.bos[idx].flags & MSM_SUBMIT_BO_READ)
+ flags |= FD_RELOC_READ;
+ if (msm_ring->submit.bos[idx].flags & MSM_SUBMIT_BO_WRITE)
+ flags |= FD_RELOC_WRITE;
+
+ relocs[i] = orig_relocs[i];
+ relocs[i].reloc_idx = bo2idx(parent, bo, flags);
+ }
+
+ /* stateobj rb's could have reloc's to other stateobj rb's which didn't
+ * get propagated to the parent rb at _emit_reloc_ring() time (because
+ * the parent wasn't known then), so fix that up now:
+ */
+ for (i = 0; i < msm_ring->nr_cmds; i++) {
+ struct msm_cmd *msm_cmd = msm_ring->cmds[i];
+ struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i];
+
+ if (msm_ring->cmds[i]->ring == stateobj)
+ continue;
+
+ assert(msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT);
+
+ if (get_cmd(parent, msm_cmd, cmd->submit_offset, cmd->size, cmd->type)) {
+ fd_ringbuffer_ref(msm_cmd->ring);
+ }
+ }
+
+ return relocs;
+}
+
static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start,
int in_fence_fd, int *out_fence_fd)
{
struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
+ struct msm_pipe *msm_pipe = to_msm_pipe(ring->pipe);
struct drm_msm_gem_submit req = {
- .flags = to_msm_pipe(ring->pipe)->pipe,
+ .flags = msm_pipe->pipe,
+ .queueid = msm_pipe->queue_id,
};
uint32_t i;
int ret;
+ assert(!ring->parent);
+
if (in_fence_fd != -1) {
req.flags |= MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_NO_IMPLICIT;
req.fence_fd = in_fence_fd;
@@ -416,22 +482,35 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
finalize_current_cmd(ring, last_start);
+ /* for each of the cmd's fix up their reloc's: */
+ for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
+ struct msm_cmd *msm_cmd = msm_ring->cmds[i];
+ struct drm_msm_gem_submit_reloc *relocs = msm_cmd->relocs;
+ struct drm_msm_gem_submit_cmd *cmd;
+ unsigned nr_relocs = msm_cmd->nr_relocs;
+
+ /* for reusable stateobjs, the reloc table has reloc_idx that
+ * points into it's own private bos table, rather than the global
+ * bos table used for the submit, so we need to add the stateobj's
+ * bos to the global table and construct new relocs table with
+ * corresponding reloc_idx
+ */
+ if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) {
+ relocs = handle_stateobj_relocs(ring, msm_cmd->ring,
+ relocs, nr_relocs);
+ }
+
+ cmd = &msm_ring->submit.cmds[i];
+ cmd->relocs = VOID2U64(relocs);
+ cmd->nr_relocs = nr_relocs;
+ }
+
/* needs to be after get_cmd() as that could create bos/cmds table: */
req.bos = VOID2U64(msm_ring->submit.bos),
req.nr_bos = msm_ring->submit.nr_bos;
req.cmds = VOID2U64(msm_ring->submit.cmds),
req.nr_cmds = msm_ring->submit.nr_cmds;
- /* for each of the cmd's fix up their reloc's: */
- for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
- struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i];
- struct msm_cmd *msm_cmd = msm_ring->cmds[i];
- uint32_t a = find_next_reloc_idx(msm_cmd, 0, cmd->submit_offset);
- uint32_t b = find_next_reloc_idx(msm_cmd, a, cmd->submit_offset + cmd->size);
- cmd->relocs = VOID2U64(&msm_cmd->relocs[a]);
- cmd->nr_relocs = (b > a) ? b - a : 0;
- }
-
DEBUG_MSG("nr_cmds=%u, nr_bos=%u", req.nr_cmds, req.nr_bos);
ret = drmCommandWriteRead(ring->pipe->dev->fd, DRM_MSM_GEM_SUBMIT,
@@ -451,6 +530,15 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
}
}
+ /* free dynamically constructed stateobj relocs tables: */
+ for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
+ struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i];
+ struct msm_cmd *msm_cmd = msm_ring->cmds[i];
+ if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) {
+ free(U642VOID(cmd->relocs));
+ }
+ }
+
flush_reset(ring);
return ret;
@@ -460,7 +548,7 @@ static void msm_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t size)
{
assert(to_msm_ringbuffer(ring)->is_growable);
finalize_current_cmd(ring, ring->last_start);
- ring_cmd_new(ring, size);
+ ring_cmd_new(ring, size, 0);
}
static void msm_ringbuffer_reset(struct fd_ringbuffer *ring)
@@ -484,7 +572,8 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
reloc->reloc_offset = r->offset;
reloc->or = r->or;
reloc->shift = r->shift;
- reloc->submit_offset = offset_bytes(ring->cur, ring->start);
+ reloc->submit_offset = offset_bytes(ring->cur, ring->start) +
+ to_msm_ringbuffer(ring)->offset;
addr = msm_bo->presumed;
if (reloc->shift < 0)
@@ -496,15 +585,21 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
if (ring->pipe->gpu_id >= 500) {
struct drm_msm_gem_submit_reloc *reloc_hi;
+ /* NOTE: grab reloc_idx *before* APPEND() since that could
+ * realloc() meaning that 'reloc' ptr is no longer valid:
+ */
+ uint32_t reloc_idx = reloc->reloc_idx;
+
idx = APPEND(cmd, relocs);
reloc_hi = &cmd->relocs[idx];
- reloc_hi->reloc_idx = reloc->reloc_idx;
+ reloc_hi->reloc_idx = reloc_idx;
reloc_hi->reloc_offset = r->offset;
reloc_hi->or = r->orhi;
reloc_hi->shift = r->shift - 32;
- reloc_hi->submit_offset = offset_bytes(ring->cur, ring->start);
+ reloc_hi->submit_offset = offset_bytes(ring->cur, ring->start) +
+ to_msm_ringbuffer(ring)->offset;
addr = msm_bo->presumed >> 32;
if (reloc_hi->shift < 0)
@@ -516,13 +611,16 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
}
static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
- struct fd_ringbuffer *target, uint32_t cmd_idx,
- uint32_t submit_offset, uint32_t size)
+ struct fd_ringbuffer *target, uint32_t cmd_idx)
{
struct msm_cmd *cmd = NULL;
+ struct msm_ringbuffer *msm_target = to_msm_ringbuffer(target);
uint32_t idx = 0;
+ int added_cmd = FALSE;
+ uint32_t size;
+ uint32_t submit_offset = msm_target->offset;
- LIST_FOR_EACH_ENTRY(cmd, &to_msm_ringbuffer(target)->cmd_list, list) {
+ LIST_FOR_EACH_ENTRY(cmd, &msm_target->cmd_list, list) {
if (idx == cmd_idx)
break;
idx++;
@@ -530,7 +628,7 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
assert(cmd && (idx == cmd_idx));
- if (idx < (to_msm_ringbuffer(target)->cmd_count - 1)) {
+ if (idx < (msm_target->cmd_count - 1)) {
/* All but the last cmd buffer is fully "baked" (ie. already has
* done get_cmd() to add it to the cmds table). But in this case,
* the size we get is invalid (since it is calculated from the
@@ -538,7 +636,10 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
*/
size = cmd->size;
} else {
- get_cmd(ring, cmd, submit_offset, size, MSM_SUBMIT_CMD_IB_TARGET_BUF);
+ struct fd_ringbuffer *parent = ring->parent ? ring->parent : ring;
+ size = offset_bytes(target->cur, target->start);
+ added_cmd = get_cmd(parent, cmd, submit_offset, size,
+ MSM_SUBMIT_CMD_IB_TARGET_BUF);
}
msm_ringbuffer_emit_reloc(ring, &(struct fd_reloc){
@@ -547,6 +648,14 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
.offset = submit_offset,
});
+ /* Unlike traditional ringbuffers which are deleted as a set (after
+ * being flushed), mesa can't really guarantee that a stateobj isn't
+ * destroyed after emitted but before flush, so we must hold a ref:
+ */
+ if (added_cmd && (target->flags & FD_RINGBUFFER_OBJECT)) {
+ fd_ringbuffer_ref(target);
+ }
+
return size;
}
@@ -581,15 +690,15 @@ static const struct fd_ringbuffer_funcs funcs = {
};
drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
- uint32_t size)
+ uint32_t size, enum fd_ringbuffer_flags flags)
{
struct msm_ringbuffer *msm_ring;
- struct fd_ringbuffer *ring = NULL;
+ struct fd_ringbuffer *ring;
msm_ring = calloc(1, sizeof(*msm_ring));
if (!msm_ring) {
ERROR_MSG("allocation failed");
- goto fail;
+ return NULL;
}
if (size == 0) {
@@ -602,15 +711,13 @@ drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
msm_ring->seqno = ++to_msm_device(pipe->dev)->ring_cnt;
ring = &msm_ring->base;
+ atomic_set(&ring->refcnt, 1);
+
ring->funcs = &funcs;
ring->size = size;
ring->pipe = pipe; /* needed in ring_cmd_new() */
- ring_cmd_new(ring, size);
+ ring_cmd_new(ring, size, flags);
return ring;
-fail:
- if (ring)
- fd_ringbuffer_del(ring);
- return NULL;
}
diff --git a/include/drm/README b/include/drm/README
index a50b02c0..ea2320cc 100644
--- a/include/drm/README
+++ b/include/drm/README
@@ -67,9 +67,11 @@ That said, it's up-to the individual developers to sync with newer version
When and how to update these files
----------------------------------
+Note: One should not do _any_ changes to the files apart from the steps below.
+
In order to update the files do the following:
- Switch to a Linux kernel tree/branch which is not rebased.
-For example: airlied/drm-next
+ For example: drm-next (https://cgit.freedesktop.org/drm/drm)
- Install the headers via `make headers_install' to a separate location.
- Copy the drm header[s] + git add + git commit.
- Note: Your commit message must include:
@@ -84,47 +86,21 @@ Outdated or Broken Headers
This section contains a list of headers and the respective "issues" they might
have relative to their kernel equivalent.
-Nearly all headers:
- - Missing extern C notation.
-Status: Trivial.
-
Most UMS headers:
- Not using fixed size integers - compat ioctls are broken.
Status: ?
Promote to fixed size ints, which match the current (32bit) ones.
-
-amdgpu_drm.h
- - Using the stdint.h uint*_t over the respective __u* ones
-Status: Trivial.
-
-drm_mode.h
- - Missing DPI encode/connector pair.
-Status: Trivial.
-
-i915_drm.h
- - Missing PARAMS - HAS_POOLED_EU, MIN_EU_IN_POOL CONTEXT_PARAM_NO_ERROR_CAPTURE
-Status: Trivial.
-
-mga_drm.h
- - Typo fix, use struct over typedef.
-Status: Trivial.
-
nouveau_drm.h
- Missing macros NOUVEAU_GETPARAM*, NOUVEAU_DRM_HEADER_PATCHLEVEL, structs,
-enums, using stdint.h over the __u* types.
-Status: ?
-
-qxl_drm.h
- - Using the stdint.h uint*_t over the respective __u* ones
-Status: Trivial.
+enums
+Status: Deliberate UABI choice; nouveau hides the exact kernel ABI behind libdrm
r128_drm.h
- Broken compat ioctls.
radeon_drm.h
- - Missing RADEON_TILING_R600_NO_SCANOUT, CIK_TILE_MODE_*, broken UMS ioctls,
-using stdint types.
+ - Missing RADEON_TILING_R600_NO_SCANOUT, CIK_TILE_MODE_*, broken UMS ioctls
- Both kernel and libdrm: missing padding -
drm_radeon_gem_{create,{g,s}et_tiling,set_domain} others ?
Status: ?
@@ -146,11 +122,6 @@ omap_drm.h (living in $TOP/omap)
- License mismatch, missing DRM_IOCTL_OMAP_GEM_NEW and related struct
Status: ?
-msm_drm.h (located in $TOP/freedreno/msm/)
- - License mismatch, missing MSM_PIPE_*, MSM_SUBMIT_*. Renamed
-drm_msm_gem_submit::flags, missing drm_msm_gem_submit::fence_fd.
-Status: ?
-
exynos_drm.h (living in $TOP/exynos)
- License mismatch, now using fixed size ints (but not everywhere). Lots of
new stuff.
diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
index d8f24976..be84e43c 100644
--- a/include/drm/amdgpu_drm.h
+++ b/include/drm/amdgpu_drm.h
@@ -50,6 +50,10 @@ extern "C" {
#define DRM_AMDGPU_WAIT_CS 0x09
#define DRM_AMDGPU_GEM_OP 0x10
#define DRM_AMDGPU_GEM_USERPTR 0x11
+#define DRM_AMDGPU_WAIT_FENCES 0x12
+#define DRM_AMDGPU_VM 0x13
+#define DRM_AMDGPU_FENCE_TO_HANDLE 0x14
+#define DRM_AMDGPU_SCHED 0x15
#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
@@ -63,13 +67,46 @@ extern "C" {
#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs)
#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
+#define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences)
+#define DRM_IOCTL_AMDGPU_VM DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm)
+#define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle)
+#define DRM_IOCTL_AMDGPU_SCHED DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched)
+/**
+ * DOC: memory domains
+ *
+ * %AMDGPU_GEM_DOMAIN_CPU System memory that is not GPU accessible.
+ * Memory in this pool could be swapped out to disk if there is pressure.
+ *
+ * %AMDGPU_GEM_DOMAIN_GTT GPU accessible system memory, mapped into the
+ * GPU's virtual address space via gart. Gart memory linearizes non-contiguous
+ * pages of system memory, allows GPU access system memory in a linezrized
+ * fashion.
+ *
+ * %AMDGPU_GEM_DOMAIN_VRAM Local video memory. For APUs, it is memory
+ * carved out by the BIOS.
+ *
+ * %AMDGPU_GEM_DOMAIN_GDS Global on-chip data storage used to share data
+ * across shader threads.
+ *
+ * %AMDGPU_GEM_DOMAIN_GWS Global wave sync, used to synchronize the
+ * execution of all the waves on a device.
+ *
+ * %AMDGPU_GEM_DOMAIN_OA Ordered append, used by 3D or Compute engines
+ * for appending data.
+ */
#define AMDGPU_GEM_DOMAIN_CPU 0x1
#define AMDGPU_GEM_DOMAIN_GTT 0x2
#define AMDGPU_GEM_DOMAIN_VRAM 0x4
#define AMDGPU_GEM_DOMAIN_GDS 0x8
#define AMDGPU_GEM_DOMAIN_GWS 0x10
#define AMDGPU_GEM_DOMAIN_OA 0x20
+#define AMDGPU_GEM_DOMAIN_MASK (AMDGPU_GEM_DOMAIN_CPU | \
+ AMDGPU_GEM_DOMAIN_GTT | \
+ AMDGPU_GEM_DOMAIN_VRAM | \
+ AMDGPU_GEM_DOMAIN_GDS | \
+ AMDGPU_GEM_DOMAIN_GWS | \
+ AMDGPU_GEM_DOMAIN_OA)
/* Flag that CPU access will be required for the case of VRAM domain */
#define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED (1 << 0)
@@ -79,22 +116,34 @@ extern "C" {
#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
/* Flag that the memory should be in VRAM and cleared */
#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
+/* Flag that create shadow bo(GTT) while allocating vram bo */
+#define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
+/* Flag that allocating the BO should use linear VRAM */
+#define AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS (1 << 5)
+/* Flag that BO is always valid in this VM */
+#define AMDGPU_GEM_CREATE_VM_ALWAYS_VALID (1 << 6)
+/* Flag that BO sharing will be explicitly synchronized */
+#define AMDGPU_GEM_CREATE_EXPLICIT_SYNC (1 << 7)
+/* Flag that indicates allocating MQD gart on GFX9, where the mtype
+ * for the second page onward should be set to NC.
+ */
+#define AMDGPU_GEM_CREATE_MQD_GFX9 (1 << 8)
struct drm_amdgpu_gem_create_in {
/** the requested memory size */
- uint64_t bo_size;
+ __u64 bo_size;
/** physical start_addr alignment in bytes for some HW requirements */
- uint64_t alignment;
+ __u64 alignment;
/** the requested memory domains */
- uint64_t domains;
+ __u64 domains;
/** allocation flags */
- uint64_t domain_flags;
+ __u64 domain_flags;
};
struct drm_amdgpu_gem_create_out {
/** returned GEM object handle */
- uint32_t handle;
- uint32_t _pad;
+ __u32 handle;
+ __u32 _pad;
};
union drm_amdgpu_gem_create {
@@ -111,28 +160,28 @@ union drm_amdgpu_gem_create {
struct drm_amdgpu_bo_list_in {
/** Type of operation */
- uint32_t operation;
+ __u32 operation;
/** Handle of list or 0 if we want to create one */
- uint32_t list_handle;
+ __u32 list_handle;
/** Number of BOs in list */
- uint32_t bo_number;
+ __u32 bo_number;
/** Size of each element describing BO */
- uint32_t bo_info_size;
+ __u32 bo_info_size;
/** Pointer to array describing BOs */
- uint64_t bo_info_ptr;
+ __u64 bo_info_ptr;
};
struct drm_amdgpu_bo_list_entry {
/** Handle of BO */
- uint32_t bo_handle;
+ __u32 bo_handle;
/** New (if specified) BO priority to be used during migration */
- uint32_t bo_priority;
+ __u32 bo_priority;
};
struct drm_amdgpu_bo_list_out {
/** Handle of resource list */
- uint32_t list_handle;
- uint32_t _pad;
+ __u32 list_handle;
+ __u32 _pad;
};
union drm_amdgpu_bo_list {
@@ -144,6 +193,7 @@ union drm_amdgpu_bo_list {
#define AMDGPU_CTX_OP_ALLOC_CTX 1
#define AMDGPU_CTX_OP_FREE_CTX 2
#define AMDGPU_CTX_OP_QUERY_STATE 3
+#define AMDGPU_CTX_OP_QUERY_STATE2 4
/* GPU reset status */
#define AMDGPU_CTX_NO_RESET 0
@@ -154,28 +204,44 @@ union drm_amdgpu_bo_list {
/* unknown cause */
#define AMDGPU_CTX_UNKNOWN_RESET 3
+/* indicate gpu reset occured after ctx created */
+#define AMDGPU_CTX_QUERY2_FLAGS_RESET (1<<0)
+/* indicate vram lost occured after ctx created */
+#define AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST (1<<1)
+/* indicate some job from this context once cause gpu hang */
+#define AMDGPU_CTX_QUERY2_FLAGS_GUILTY (1<<2)
+
+/* Context priority level */
+#define AMDGPU_CTX_PRIORITY_UNSET -2048
+#define AMDGPU_CTX_PRIORITY_VERY_LOW -1023
+#define AMDGPU_CTX_PRIORITY_LOW -512
+#define AMDGPU_CTX_PRIORITY_NORMAL 0
+/* Selecting a priority above NORMAL requires CAP_SYS_NICE or DRM_MASTER */
+#define AMDGPU_CTX_PRIORITY_HIGH 512
+#define AMDGPU_CTX_PRIORITY_VERY_HIGH 1023
+
struct drm_amdgpu_ctx_in {
/** AMDGPU_CTX_OP_* */
- uint32_t op;
+ __u32 op;
/** For future use, no flags defined so far */
- uint32_t flags;
- uint32_t ctx_id;
- uint32_t _pad;
+ __u32 flags;
+ __u32 ctx_id;
+ __s32 priority;
};
union drm_amdgpu_ctx_out {
struct {
- uint32_t ctx_id;
- uint32_t _pad;
+ __u32 ctx_id;
+ __u32 _pad;
} alloc;
struct {
/** For future use, no flags defined so far */
- uint64_t flags;
+ __u64 flags;
/** Number of resets caused by this context so far. */
- uint32_t hangs;
+ __u32 hangs;
/** Reset status since the last call of the ioctl. */
- uint32_t reset_status;
+ __u32 reset_status;
} state;
};
@@ -184,6 +250,41 @@ union drm_amdgpu_ctx {
union drm_amdgpu_ctx_out out;
};
+/* vm ioctl */
+#define AMDGPU_VM_OP_RESERVE_VMID 1
+#define AMDGPU_VM_OP_UNRESERVE_VMID 2
+
+struct drm_amdgpu_vm_in {
+ /** AMDGPU_VM_OP_* */
+ __u32 op;
+ __u32 flags;
+};
+
+struct drm_amdgpu_vm_out {
+ /** For future use, no flags defined so far */
+ __u64 flags;
+};
+
+union drm_amdgpu_vm {
+ struct drm_amdgpu_vm_in in;
+ struct drm_amdgpu_vm_out out;
+};
+
+/* sched ioctl */
+#define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE 1
+
+struct drm_amdgpu_sched_in {
+ /* AMDGPU_SCHED_OP_* */
+ __u32 op;
+ __u32 fd;
+ __s32 priority;
+ __u32 flags;
+};
+
+union drm_amdgpu_sched {
+ struct drm_amdgpu_sched_in in;
+};
+
/*
* This is not a reliable API and you should expect it to fail for any
* number of reasons and have fallback path that do not use userptr to
@@ -195,14 +296,15 @@ union drm_amdgpu_ctx {
#define AMDGPU_GEM_USERPTR_REGISTER (1 << 3)
struct drm_amdgpu_gem_userptr {
- uint64_t addr;
- uint64_t size;
+ __u64 addr;
+ __u64 size;
/* AMDGPU_GEM_USERPTR_* */
- uint32_t flags;
+ __u32 flags;
/* Resulting GEM handle */
- uint32_t handle;
+ __u32 handle;
};
+/* SI-CI-VI: */
/* same meaning as the GB_TILE_MODE and GL_MACRO_TILE_MODE fields */
#define AMDGPU_TILING_ARRAY_MODE_SHIFT 0
#define AMDGPU_TILING_ARRAY_MODE_MASK 0xf
@@ -221,10 +323,21 @@ struct drm_amdgpu_gem_userptr {
#define AMDGPU_TILING_NUM_BANKS_SHIFT 21
#define AMDGPU_TILING_NUM_BANKS_MASK 0x3
+/* GFX9 and later: */
+#define AMDGPU_TILING_SWIZZLE_MODE_SHIFT 0
+#define AMDGPU_TILING_SWIZZLE_MODE_MASK 0x1f
+#define AMDGPU_TILING_DCC_OFFSET_256B_SHIFT 5
+#define AMDGPU_TILING_DCC_OFFSET_256B_MASK 0xFFFFFF
+#define AMDGPU_TILING_DCC_PITCH_MAX_SHIFT 29
+#define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF
+#define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43
+#define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1
+
+/* Set/Get helpers for tiling flags. */
#define AMDGPU_TILING_SET(field, value) \
- (((value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT)
+ (((__u64)(value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT)
#define AMDGPU_TILING_GET(value, field) \
- (((value) >> AMDGPU_TILING_##field##_SHIFT) & AMDGPU_TILING_##field##_MASK)
+ (((__u64)(value) >> AMDGPU_TILING_##field##_SHIFT) & AMDGPU_TILING_##field##_MASK)
#define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
#define AMDGPU_GEM_METADATA_OP_GET_METADATA 2
@@ -232,28 +345,28 @@ struct drm_amdgpu_gem_userptr {
/** The same structure is shared for input/output */
struct drm_amdgpu_gem_metadata {
/** GEM Object handle */
- uint32_t handle;
+ __u32 handle;
/** Do we want get or set metadata */
- uint32_t op;
+ __u32 op;
struct {
/** For future use, no flags defined so far */
- uint64_t flags;
+ __u64 flags;
/** family specific tiling info */
- uint64_t tiling_info;
- uint32_t data_size_bytes;
- uint32_t data[64];
+ __u64 tiling_info;
+ __u32 data_size_bytes;
+ __u32 data[64];
} data;
};
struct drm_amdgpu_gem_mmap_in {
/** the GEM object handle */
- uint32_t handle;
- uint32_t _pad;
+ __u32 handle;
+ __u32 _pad;
};
struct drm_amdgpu_gem_mmap_out {
/** mmap offset from the vma offset manager */
- uint64_t addr_ptr;
+ __u64 addr_ptr;
};
union drm_amdgpu_gem_mmap {
@@ -263,18 +376,18 @@ union drm_amdgpu_gem_mmap {
struct drm_amdgpu_gem_wait_idle_in {
/** GEM object handle */
- uint32_t handle;
+ __u32 handle;
/** For future use, no flags defined so far */
- uint32_t flags;
+ __u32 flags;
/** Absolute timeout to wait */
- uint64_t timeout;
+ __u64 timeout;
};
struct drm_amdgpu_gem_wait_idle_out {
/** BO status: 0 - BO is idle, 1 - BO is busy */
- uint32_t status;
+ __u32 status;
/** Returned current memory domain */
- uint32_t domain;
+ __u32 domain;
};
union drm_amdgpu_gem_wait_idle {
@@ -283,19 +396,22 @@ union drm_amdgpu_gem_wait_idle {
};
struct drm_amdgpu_wait_cs_in {
- /** Command submission handle */
- uint64_t handle;
+ /* Command submission handle
+ * handle equals 0 means none to wait for
+ * handle equals ~0ull means wait for the latest sequence number
+ */
+ __u64 handle;
/** Absolute timeout to wait */
- uint64_t timeout;
- uint32_t ip_type;
- uint32_t ip_instance;
- uint32_t ring;
- uint32_t ctx_id;
+ __u64 timeout;
+ __u32 ip_type;
+ __u32 ip_instance;
+ __u32 ring;
+ __u32 ctx_id;
};
struct drm_amdgpu_wait_cs_out {
/** CS status: 0 - CS completed, 1 - CS still busy */
- uint64_t status;
+ __u64 status;
};
union drm_amdgpu_wait_cs {
@@ -303,21 +419,49 @@ union drm_amdgpu_wait_cs {
struct drm_amdgpu_wait_cs_out out;
};
+struct drm_amdgpu_fence {
+ __u32 ctx_id;
+ __u32 ip_type;
+ __u32 ip_instance;
+ __u32 ring;
+ __u64 seq_no;
+};
+
+struct drm_amdgpu_wait_fences_in {
+ /** This points to uint64_t * which points to fences */
+ __u64 fences;
+ __u32 fence_count;
+ __u32 wait_all;
+ __u64 timeout_ns;
+};
+
+struct drm_amdgpu_wait_fences_out {
+ __u32 status;
+ __u32 first_signaled;
+};
+
+union drm_amdgpu_wait_fences {
+ struct drm_amdgpu_wait_fences_in in;
+ struct drm_amdgpu_wait_fences_out out;
+};
+
#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0
#define AMDGPU_GEM_OP_SET_PLACEMENT 1
/* Sets or returns a value associated with a buffer. */
struct drm_amdgpu_gem_op {
/** GEM object handle */
- uint32_t handle;
+ __u32 handle;
/** AMDGPU_GEM_OP_* */
- uint32_t op;
+ __u32 op;
/** Input or return value */
- uint64_t value;
+ __u64 value;
};
#define AMDGPU_VA_OP_MAP 1
#define AMDGPU_VA_OP_UNMAP 2
+#define AMDGPU_VA_OP_CLEAR 3
+#define AMDGPU_VA_OP_REPLACE 4
/* Delay the page table update till the next CS */
#define AMDGPU_VM_DELAY_UPDATE (1 << 0)
@@ -329,21 +473,35 @@ struct drm_amdgpu_gem_op {
#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2)
/* executable mapping, new for VI */
#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3)
+/* partially resident texture */
+#define AMDGPU_VM_PAGE_PRT (1 << 4)
+/* MTYPE flags use bit 5 to 8 */
+#define AMDGPU_VM_MTYPE_MASK (0xf << 5)
+/* Default MTYPE. Pre-AI must use this. Recommended for newer ASICs. */
+#define AMDGPU_VM_MTYPE_DEFAULT (0 << 5)
+/* Use NC MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_NC (1 << 5)
+/* Use WC MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_WC (2 << 5)
+/* Use CC MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_CC (3 << 5)
+/* Use UC MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_UC (4 << 5)
struct drm_amdgpu_gem_va {
/** GEM object handle */
- uint32_t handle;
- uint32_t _pad;
+ __u32 handle;
+ __u32 _pad;
/** AMDGPU_VA_OP_* */
- uint32_t operation;
+ __u32 operation;
/** AMDGPU_VM_PAGE_* */
- uint32_t flags;
+ __u32 flags;
/** va address to assign . Must be correctly aligned.*/
- uint64_t va_address;
+ __u64 va_address;
/** Specify offset inside of BO to assign. Must be correctly aligned.*/
- uint64_t offset_in_bo;
+ __u64 offset_in_bo;
/** Specify mapping size. Must be correctly aligned. */
- uint64_t map_size;
+ __u64 map_size;
};
#define AMDGPU_HW_IP_GFX 0
@@ -351,33 +509,40 @@ struct drm_amdgpu_gem_va {
#define AMDGPU_HW_IP_DMA 2
#define AMDGPU_HW_IP_UVD 3
#define AMDGPU_HW_IP_VCE 4
-#define AMDGPU_HW_IP_NUM 5
+#define AMDGPU_HW_IP_UVD_ENC 5
+#define AMDGPU_HW_IP_VCN_DEC 6
+#define AMDGPU_HW_IP_VCN_ENC 7
+#define AMDGPU_HW_IP_VCN_JPEG 8
+#define AMDGPU_HW_IP_NUM 9
#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
#define AMDGPU_CHUNK_ID_IB 0x01
#define AMDGPU_CHUNK_ID_FENCE 0x02
#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
+#define AMDGPU_CHUNK_ID_SYNCOBJ_IN 0x04
+#define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
+#define AMDGPU_CHUNK_ID_BO_HANDLES 0x06
struct drm_amdgpu_cs_chunk {
- uint32_t chunk_id;
- uint32_t length_dw;
- uint64_t chunk_data;
+ __u32 chunk_id;
+ __u32 length_dw;
+ __u64 chunk_data;
};
struct drm_amdgpu_cs_in {
/** Rendering context id */
- uint32_t ctx_id;
+ __u32 ctx_id;
/** Handle of resource list associated with CS */
- uint32_t bo_list_handle;
- uint32_t num_chunks;
- uint32_t _pad;
- /** this points to uint64_t * which point to cs chunks */
- uint64_t chunks;
+ __u32 bo_list_handle;
+ __u32 num_chunks;
+ __u32 _pad;
+ /** this points to __u64 * which point to cs chunks */
+ __u64 chunks;
};
struct drm_amdgpu_cs_out {
- uint64_t handle;
+ __u64 handle;
};
union drm_amdgpu_cs {
@@ -390,36 +555,62 @@ union drm_amdgpu_cs {
/* This IB should be submitted to CE */
#define AMDGPU_IB_FLAG_CE (1<<0)
-/* CE Preamble */
+/* Preamble flag, which means the IB could be dropped if no context switch */
#define AMDGPU_IB_FLAG_PREAMBLE (1<<1)
+/* Preempt flag, IB should set Pre_enb bit if PREEMPT flag detected */
+#define AMDGPU_IB_FLAG_PREEMPT (1<<2)
+
+/* The IB fence should do the L2 writeback but not invalidate any shader
+ * caches (L2/vL1/sL1/I$). */
+#define AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE (1 << 3)
+
struct drm_amdgpu_cs_chunk_ib {
- uint32_t _pad;
+ __u32 _pad;
/** AMDGPU_IB_FLAG_* */
- uint32_t flags;
+ __u32 flags;
/** Virtual address to begin IB execution */
- uint64_t va_start;
+ __u64 va_start;
/** Size of submission */
- uint32_t ib_bytes;
+ __u32 ib_bytes;
/** HW IP to submit to */
- uint32_t ip_type;
+ __u32 ip_type;
/** HW IP index of the same type to submit to */
- uint32_t ip_instance;
+ __u32 ip_instance;
/** Ring index to submit to */
- uint32_t ring;
+ __u32 ring;
};
struct drm_amdgpu_cs_chunk_dep {
- uint32_t ip_type;
- uint32_t ip_instance;
- uint32_t ring;
- uint32_t ctx_id;
- uint64_t handle;
+ __u32 ip_type;
+ __u32 ip_instance;
+ __u32 ring;
+ __u32 ctx_id;
+ __u64 handle;
};
struct drm_amdgpu_cs_chunk_fence {
- uint32_t handle;
- uint32_t offset;
+ __u32 handle;
+ __u32 offset;
+};
+
+struct drm_amdgpu_cs_chunk_sem {
+ __u32 handle;
+};
+
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2
+
+union drm_amdgpu_fence_to_handle {
+ struct {
+ struct drm_amdgpu_fence fence;
+ __u32 what;
+ __u32 pad;
+ } in;
+ struct {
+ __u32 handle;
+ } out;
};
struct drm_amdgpu_cs_chunk_data {
@@ -434,6 +625,7 @@ struct drm_amdgpu_cs_chunk_data {
*
*/
#define AMDGPU_IDS_FLAGS_FUSION 0x1
+#define AMDGPU_IDS_FLAGS_PREEMPTION 0x2
/* indicate if acceleration can be working */
#define AMDGPU_INFO_ACCEL_WORKING 0x00
@@ -467,6 +659,20 @@ struct drm_amdgpu_cs_chunk_data {
#define AMDGPU_INFO_FW_SMC 0x0a
/* Subquery id: Query SDMA firmware version */
#define AMDGPU_INFO_FW_SDMA 0x0b
+ /* Subquery id: Query PSP SOS firmware version */
+ #define AMDGPU_INFO_FW_SOS 0x0c
+ /* Subquery id: Query PSP ASD firmware version */
+ #define AMDGPU_INFO_FW_ASD 0x0d
+ /* Subquery id: Query VCN firmware version */
+ #define AMDGPU_INFO_FW_VCN 0x0e
+ /* Subquery id: Query GFX RLC SRLC firmware version */
+ #define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL 0x0f
+ /* Subquery id: Query GFX RLC SRLG firmware version */
+ #define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM 0x10
+ /* Subquery id: Query GFX RLC SRLS firmware version */
+ #define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM 0x11
+ /* Subquery id: Query DMCU firmware version */
+ #define AMDGPU_INFO_FW_DMCU 0x12
/* number of bytes moved for TTM migration */
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
/* the used VRAM size */
@@ -483,6 +689,43 @@ struct drm_amdgpu_cs_chunk_data {
#define AMDGPU_INFO_DEV_INFO 0x16
/* visible vram usage */
#define AMDGPU_INFO_VIS_VRAM_USAGE 0x17
+/* number of TTM buffer evictions */
+#define AMDGPU_INFO_NUM_EVICTIONS 0x18
+/* Query memory about VRAM and GTT domains */
+#define AMDGPU_INFO_MEMORY 0x19
+/* Query vce clock table */
+#define AMDGPU_INFO_VCE_CLOCK_TABLE 0x1A
+/* Query vbios related information */
+#define AMDGPU_INFO_VBIOS 0x1B
+ /* Subquery id: Query vbios size */
+ #define AMDGPU_INFO_VBIOS_SIZE 0x1
+ /* Subquery id: Query vbios image */
+ #define AMDGPU_INFO_VBIOS_IMAGE 0x2
+/* Query UVD handles */
+#define AMDGPU_INFO_NUM_HANDLES 0x1C
+/* Query sensor related information */
+#define AMDGPU_INFO_SENSOR 0x1D
+ /* Subquery id: Query GPU shader clock */
+ #define AMDGPU_INFO_SENSOR_GFX_SCLK 0x1
+ /* Subquery id: Query GPU memory clock */
+ #define AMDGPU_INFO_SENSOR_GFX_MCLK 0x2
+ /* Subquery id: Query GPU temperature */
+ #define AMDGPU_INFO_SENSOR_GPU_TEMP 0x3
+ /* Subquery id: Query GPU load */
+ #define AMDGPU_INFO_SENSOR_GPU_LOAD 0x4
+ /* Subquery id: Query average GPU power */
+ #define AMDGPU_INFO_SENSOR_GPU_AVG_POWER 0x5
+ /* Subquery id: Query northbridge voltage */
+ #define AMDGPU_INFO_SENSOR_VDDNB 0x6
+ /* Subquery id: Query graphics voltage */
+ #define AMDGPU_INFO_SENSOR_VDDGFX 0x7
+ /* Subquery id: Query GPU stable pstate shader clock */
+ #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK 0x8
+ /* Subquery id: Query GPU stable pstate memory clock */
+ #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK 0x9
+/* Number of VRAM page faults on CPU access. */
+#define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
+#define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F
#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
@@ -491,86 +734,123 @@ struct drm_amdgpu_cs_chunk_data {
struct drm_amdgpu_query_fw {
/** AMDGPU_INFO_FW_* */
- uint32_t fw_type;
+ __u32 fw_type;
/**
* Index of the IP if there are more IPs of
* the same type.
*/
- uint32_t ip_instance;
+ __u32 ip_instance;
/**
* Index of the engine. Whether this is used depends
* on the firmware type. (e.g. MEC, SDMA)
*/
- uint32_t index;
- uint32_t _pad;
+ __u32 index;
+ __u32 _pad;
};
/* Input structure for the INFO ioctl */
struct drm_amdgpu_info {
/* Where the return value will be stored */
- uint64_t return_pointer;
+ __u64 return_pointer;
/* The size of the return value. Just like "size" in "snprintf",
* it limits how many bytes the kernel can write. */
- uint32_t return_size;
+ __u32 return_size;
/* The query request id. */
- uint32_t query;
+ __u32 query;
union {
struct {
- uint32_t id;
- uint32_t _pad;
+ __u32 id;
+ __u32 _pad;
} mode_crtc;
struct {
/** AMDGPU_HW_IP_* */
- uint32_t type;
+ __u32 type;
/**
* Index of the IP if there are more IPs of the same
* type. Ignored by AMDGPU_INFO_HW_IP_COUNT.
*/
- uint32_t ip_instance;
+ __u32 ip_instance;
} query_hw_ip;
struct {
- uint32_t dword_offset;
+ __u32 dword_offset;
/** number of registers to read */
- uint32_t count;
- uint32_t instance;
+ __u32 count;
+ __u32 instance;
/** For future use, no flags defined so far */
- uint32_t flags;
+ __u32 flags;
} read_mmr_reg;
struct drm_amdgpu_query_fw query_fw;
+
+ struct {
+ __u32 type;
+ __u32 offset;
+ } vbios_info;
+
+ struct {
+ __u32 type;
+ } sensor_info;
};
};
struct drm_amdgpu_info_gds {
/** GDS GFX partition size */
- uint32_t gds_gfx_partition_size;
+ __u32 gds_gfx_partition_size;
/** GDS compute partition size */
- uint32_t compute_partition_size;
+ __u32 compute_partition_size;
/** total GDS memory size */
- uint32_t gds_total_size;
+ __u32 gds_total_size;
/** GWS size per GFX partition */
- uint32_t gws_per_gfx_partition;
+ __u32 gws_per_gfx_partition;
/** GSW size per compute partition */
- uint32_t gws_per_compute_partition;
+ __u32 gws_per_compute_partition;
/** OA size per GFX partition */
- uint32_t oa_per_gfx_partition;
+ __u32 oa_per_gfx_partition;
/** OA size per compute partition */
- uint32_t oa_per_compute_partition;
- uint32_t _pad;
+ __u32 oa_per_compute_partition;
+ __u32 _pad;
};
struct drm_amdgpu_info_vram_gtt {
- uint64_t vram_size;
- uint64_t vram_cpu_accessible_size;
- uint64_t gtt_size;
+ __u64 vram_size;
+ __u64 vram_cpu_accessible_size;
+ __u64 gtt_size;
+};
+
+struct drm_amdgpu_heap_info {
+ /** max. physical memory */
+ __u64 total_heap_size;
+
+ /** Theoretical max. available memory in the given heap */
+ __u64 usable_heap_size;
+
+ /**
+ * Number of bytes allocated in the heap. This includes all processes
+ * and private allocations in the kernel. It changes when new buffers
+ * are allocated, freed, and moved. It cannot be larger than
+ * heap_size.
+ */
+ __u64 heap_usage;
+
+ /**
+ * Theoretical possible max. size of buffer which
+ * could be allocated in the given heap
+ */
+ __u64 max_allocation;
+};
+
+struct drm_amdgpu_memory_info {
+ struct drm_amdgpu_heap_info vram;
+ struct drm_amdgpu_heap_info cpu_accessible_vram;
+ struct drm_amdgpu_heap_info gtt;
};
struct drm_amdgpu_info_firmware {
- uint32_t ver;
- uint32_t feature;
+ __u32 ver;
+ __u32 feature;
};
#define AMDGPU_VRAM_TYPE_UNKNOWN 0
@@ -581,74 +861,139 @@ struct drm_amdgpu_info_firmware {
#define AMDGPU_VRAM_TYPE_GDDR5 5
#define AMDGPU_VRAM_TYPE_HBM 6
#define AMDGPU_VRAM_TYPE_DDR3 7
+#define AMDGPU_VRAM_TYPE_DDR4 8
struct drm_amdgpu_info_device {
/** PCI Device ID */
- uint32_t device_id;
+ __u32 device_id;
/** Internal chip revision: A0, A1, etc.) */
- uint32_t chip_rev;
- uint32_t external_rev;
+ __u32 chip_rev;
+ __u32 external_rev;
/** Revision id in PCI Config space */
- uint32_t pci_rev;
- uint32_t family;
- uint32_t num_shader_engines;
- uint32_t num_shader_arrays_per_engine;
+ __u32 pci_rev;
+ __u32 family;
+ __u32 num_shader_engines;
+ __u32 num_shader_arrays_per_engine;
/* in KHz */
- uint32_t gpu_counter_freq;
- uint64_t max_engine_clock;
- uint64_t max_memory_clock;
+ __u32 gpu_counter_freq;
+ __u64 max_engine_clock;
+ __u64 max_memory_clock;
/* cu information */
- uint32_t cu_active_number;
- uint32_t cu_ao_mask;
- uint32_t cu_bitmap[4][4];
+ __u32 cu_active_number;
+ /* NOTE: cu_ao_mask is INVALID, DON'T use it */
+ __u32 cu_ao_mask;
+ __u32 cu_bitmap[4][4];
/** Render backend pipe mask. One render backend is CB+DB. */
- uint32_t enabled_rb_pipes_mask;
- uint32_t num_rb_pipes;
- uint32_t num_hw_gfx_contexts;
- uint32_t _pad;
- uint64_t ids_flags;
+ __u32 enabled_rb_pipes_mask;
+ __u32 num_rb_pipes;
+ __u32 num_hw_gfx_contexts;
+ __u32 _pad;
+ __u64 ids_flags;
/** Starting virtual address for UMDs. */
- uint64_t virtual_address_offset;
+ __u64 virtual_address_offset;
/** The maximum virtual address */
- uint64_t virtual_address_max;
+ __u64 virtual_address_max;
/** Required alignment of virtual addresses. */
- uint32_t virtual_address_alignment;
+ __u32 virtual_address_alignment;
/** Page table entry - fragment size */
- uint32_t pte_fragment_size;
- uint32_t gart_page_size;
+ __u32 pte_fragment_size;
+ __u32 gart_page_size;
/** constant engine ram size*/
- uint32_t ce_ram_size;
+ __u32 ce_ram_size;
/** video memory type info*/
- uint32_t vram_type;
+ __u32 vram_type;
/** video memory bit width*/
- uint32_t vram_bit_width;
+ __u32 vram_bit_width;
/* vce harvesting instance */
- uint32_t vce_harvest_config;
+ __u32 vce_harvest_config;
+ /* gfx double offchip LDS buffers */
+ __u32 gc_double_offchip_lds_buf;
+ /* NGG Primitive Buffer */
+ __u64 prim_buf_gpu_addr;
+ /* NGG Position Buffer */
+ __u64 pos_buf_gpu_addr;
+ /* NGG Control Sideband */
+ __u64 cntl_sb_buf_gpu_addr;
+ /* NGG Parameter Cache */
+ __u64 param_buf_gpu_addr;
+ __u32 prim_buf_size;
+ __u32 pos_buf_size;
+ __u32 cntl_sb_buf_size;
+ __u32 param_buf_size;
+ /* wavefront size*/
+ __u32 wave_front_size;
+ /* shader visible vgprs*/
+ __u32 num_shader_visible_vgprs;
+ /* CU per shader array*/
+ __u32 num_cu_per_sh;
+ /* number of tcc blocks*/
+ __u32 num_tcc_blocks;
+ /* gs vgt table depth*/
+ __u32 gs_vgt_table_depth;
+ /* gs primitive buffer depth*/
+ __u32 gs_prim_buffer_depth;
+ /* max gs wavefront per vgt*/
+ __u32 max_gs_waves_per_vgt;
+ __u32 _pad1;
+ /* always on cu bitmap */
+ __u32 cu_ao_bitmap[4][4];
+ /** Starting high virtual address for UMDs. */
+ __u64 high_va_offset;
+ /** The maximum high virtual address */
+ __u64 high_va_max;
};
struct drm_amdgpu_info_hw_ip {
/** Version of h/w IP */
- uint32_t hw_ip_version_major;
- uint32_t hw_ip_version_minor;
+ __u32 hw_ip_version_major;
+ __u32 hw_ip_version_minor;
/** Capabilities */
- uint64_t capabilities_flags;
+ __u64 capabilities_flags;
/** command buffer address start alignment*/
- uint32_t ib_start_alignment;
+ __u32 ib_start_alignment;
/** command buffer size alignment*/
- uint32_t ib_size_alignment;
+ __u32 ib_size_alignment;
/** Bitmask of available rings. Bit 0 means ring 0, etc. */
- uint32_t available_rings;
- uint32_t _pad;
+ __u32 available_rings;
+ __u32 _pad;
+};
+
+struct drm_amdgpu_info_num_handles {
+ /** Max handles as supported by firmware for UVD */
+ __u32 uvd_max_handles;
+ /** Handles currently in use for UVD */
+ __u32 uvd_used_handles;
+};
+
+#define AMDGPU_VCE_CLOCK_TABLE_ENTRIES 6
+
+struct drm_amdgpu_info_vce_clock_table_entry {
+ /** System clock */
+ __u32 sclk;
+ /** Memory clock */
+ __u32 mclk;
+ /** VCE clock */
+ __u32 eclk;
+ __u32 pad;
+};
+
+struct drm_amdgpu_info_vce_clock_table {
+ struct drm_amdgpu_info_vce_clock_table_entry entries[AMDGPU_VCE_CLOCK_TABLE_ENTRIES];
+ __u32 num_valid_entries;
+ __u32 pad;
};
/*
* Supported GPU families
*/
#define AMDGPU_FAMILY_UNKNOWN 0
+#define AMDGPU_FAMILY_SI 110 /* Hainan, Oland, Verde, Pitcairn, Tahiti */
#define AMDGPU_FAMILY_CI 120 /* Bonaire, Hawaii */
#define AMDGPU_FAMILY_KV 125 /* Kaveri, Kabini, Mullins */
#define AMDGPU_FAMILY_VI 130 /* Iceland, Tonga */
#define AMDGPU_FAMILY_CZ 135 /* Carrizo, Stoney */
+#define AMDGPU_FAMILY_AI 141 /* Vega10 */
+#define AMDGPU_FAMILY_RV 142 /* Raven */
#if defined(__cplusplus)
}
diff --git a/include/drm/drm.h b/include/drm/drm.h
index f6fd5c2c..85c685a2 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -641,6 +641,8 @@ struct drm_gem_open {
#define DRM_CAP_CURSOR_HEIGHT 0x9
#define DRM_CAP_ADDFB2_MODIFIERS 0x10
#define DRM_CAP_PAGE_FLIP_TARGET 0x11
+#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12
+#define DRM_CAP_SYNCOBJ 0x13
/** DRM_IOCTL_GET_CAP ioctl argument type */
struct drm_get_cap {
@@ -672,6 +674,22 @@ struct drm_get_cap {
*/
#define DRM_CLIENT_CAP_ATOMIC 3
+/**
+ * DRM_CLIENT_CAP_ASPECT_RATIO
+ *
+ * If set to 1, the DRM core will provide aspect ratio information in modes.
+ */
+#define DRM_CLIENT_CAP_ASPECT_RATIO 4
+
+/**
+ * DRM_CLIENT_CAP_WRITEBACK_CONNECTORS
+ *
+ * If set to 1, the DRM core will expose special connectors to be used for
+ * writing back to memory the scene setup in the commit. Depends on client
+ * also supporting DRM_CLIENT_CAP_ATOMIC
+ */
+#define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 5
+
/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
struct drm_set_client_cap {
__u64 capability;
@@ -690,6 +708,67 @@ struct drm_prime_handle {
__s32 fd;
};
+struct drm_syncobj_create {
+ __u32 handle;
+#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0)
+ __u32 flags;
+};
+
+struct drm_syncobj_destroy {
+ __u32 handle;
+ __u32 pad;
+};
+
+#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0)
+#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0)
+struct drm_syncobj_handle {
+ __u32 handle;
+ __u32 flags;
+
+ __s32 fd;
+ __u32 pad;
+};
+
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+struct drm_syncobj_wait {
+ __u64 handles;
+ /* absolute timeout */
+ __s64 timeout_nsec;
+ __u32 count_handles;
+ __u32 flags;
+ __u32 first_signaled; /* only valid when not waiting all */
+ __u32 pad;
+};
+
+struct drm_syncobj_array {
+ __u64 handles;
+ __u32 count_handles;
+ __u32 pad;
+};
+
+/* Query current scanout sequence number */
+struct drm_crtc_get_sequence {
+ __u32 crtc_id; /* requested crtc_id */
+ __u32 active; /* return: crtc output is active */
+ __u64 sequence; /* return: most recent vblank sequence */
+ __s64 sequence_ns; /* return: most recent time of first pixel out */
+};
+
+/* Queue event to be delivered at specified sequence. Time stamp marks
+ * when the first pixel of the refresh cycle leaves the display engine
+ * for the display
+ */
+#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001 /* sequence is relative to current */
+#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002 /* Use next sequence if we've missed */
+
+struct drm_crtc_queue_sequence {
+ __u32 crtc_id;
+ __u32 flags;
+ __u64 sequence; /* on input, target sequence. on output, actual sequence */
+ __u64 user_data; /* user data passed to event */
+};
+
#if defined(__cplusplus)
}
#endif
@@ -772,6 +851,9 @@ extern "C" {
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
+#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence)
+#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence)
+
#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
@@ -808,6 +890,19 @@ extern "C" {
#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob)
#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob)
+#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create)
+#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy)
+#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait)
+#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
+#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
+
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
+
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
@@ -838,6 +933,7 @@ struct drm_event {
#define DRM_EVENT_VBLANK 0x01
#define DRM_EVENT_FLIP_COMPLETE 0x02
+#define DRM_EVENT_CRTC_SEQUENCE 0x03
struct drm_event_vblank {
struct drm_event base;
@@ -845,7 +941,17 @@ struct drm_event_vblank {
__u32 tv_sec;
__u32 tv_usec;
__u32 sequence;
- __u32 reserved;
+ __u32 crtc_id; /* 0 on older kernels that do not support this */
+};
+
+/* Event delivered at sequence. Time stamp marks when the first pixel
+ * of the refresh cycle leaves the display engine for the display
+ */
+struct drm_event_crtc_sequence {
+ struct drm_event base;
+ __u64 user_data;
+ __s64 time_ns;
+ __u64 sequence;
};
/* typedef area */
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 4d8da699..139632b8 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -26,21 +26,71 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * DOC: overview
+ *
+ * In the DRM subsystem, framebuffer pixel formats are described using the
+ * fourcc codes defined in `include/uapi/drm/drm_fourcc.h`. In addition to the
+ * fourcc code, a Format Modifier may optionally be provided, in order to
+ * further describe the buffer's format - for example tiling or compression.
+ *
+ * Format Modifiers
+ * ----------------
+ *
+ * Format modifiers are used in conjunction with a fourcc code, forming a
+ * unique fourcc:modifier pair. This format:modifier pair must fully define the
+ * format and data layout of the buffer, and should be the only way to describe
+ * that particular buffer.
+ *
+ * Having multiple fourcc:modifier pairs which describe the same layout should
+ * be avoided, as such aliases run the risk of different drivers exposing
+ * different names for the same data format, forcing userspace to understand
+ * that they are aliases.
+ *
+ * Format modifiers may change any property of the buffer, including the number
+ * of planes and/or the required allocation size. Format modifiers are
+ * vendor-namespaced, and as such the relationship between a fourcc code and a
+ * modifier is specific to the modifer being used. For example, some modifiers
+ * may preserve meaning - such as number of planes - from the fourcc code,
+ * whereas others may not.
+ *
+ * Vendors should document their modifier usage in as much detail as
+ * possible, to ensure maximum compatibility across devices, drivers and
+ * applications.
+ *
+ * The authoritative list of format modifier codes is found in
+ * `include/uapi/drm/drm_fourcc.h`
+ */
+
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
((__u32)(c) << 16) | ((__u32)(d) << 24))
#define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */
+/* Reserve 0 for the invalid format specifier */
+#define DRM_FORMAT_INVALID 0
+
/* color index */
#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ') /* [7:0] C */
/* 8 bpp Red */
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
+/* 16 bpp Red */
+#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ') /* [15:0] R little endian */
+
/* 16 bpp RG */
#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */
#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */
+/* 32 bpp RG */
+#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2') /* [31:0] R:G 16:16 little endian */
+#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] G:R 16:16 little endian */
+
/* 8 bpp RGB */
#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */
#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */
@@ -103,6 +153,20 @@
#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
/*
+ * 2 plane RGB + A
+ * index 0 = RGB plane, same format as the corresponding non _A8 format has
+ * index 1 = A plane, [7:0] A
+ */
+#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8')
+#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8')
+#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8')
+#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8')
+#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8')
+#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8')
+#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8')
+#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8')
+
+/*
* 2 plane YCbCr
* index 0 = Y plane, [7:0] Y
* index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
@@ -150,15 +214,21 @@
/* Vendor Ids: */
#define DRM_FORMAT_MOD_NONE 0
+#define DRM_FORMAT_MOD_VENDOR_NONE 0
#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01
#define DRM_FORMAT_MOD_VENDOR_AMD 0x02
-#define DRM_FORMAT_MOD_VENDOR_NV 0x03
+#define DRM_FORMAT_MOD_VENDOR_NVIDIA 0x03
#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
+#define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06
+#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
+#define DRM_FORMAT_MOD_VENDOR_ARM 0x08
/* add more to the end as needed */
+#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
+
#define fourcc_mod_code(vendor, val) \
- ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
+ ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | ((val) & 0x00ffffffffffffffULL))
/*
* Format Modifier tokens:
@@ -168,6 +238,25 @@
* authoritative source for all of these.
*/
+/*
+ * Invalid Modifier
+ *
+ * This modifier can be used as a sentinel to terminate the format modifiers
+ * list, or to initialize a variable with an invalid modifier. It might also be
+ * used to report an error back to userspace for certain APIs.
+ */
+#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
+
+/*
+ * Linear Layout
+ *
+ * Just plain linear layout. Note that this is different from no specifying any
+ * modifier (e.g. not setting DRM_MODE_FB_MODIFIERS in the DRM_ADDFB2 ioctl),
+ * which tells the driver to also take driver-internal information into account
+ * and so might actually result in a tiled framebuffer.
+ */
+#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
+
/* Intel framebuffer modifiers */
/*
@@ -215,6 +304,26 @@
#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
/*
+ * Intel color control surface (CCS) for render compression
+ *
+ * The framebuffer format must be one of the 8:8:8:8 RGB formats.
+ * The main surface will be plane index 0 and must be Y/Yf-tiled,
+ * the CCS will be plane index 1.
+ *
+ * Each CCS tile matches a 1024x512 pixel area of the main surface.
+ * To match certain aspects of the 3D hardware the CCS is
+ * considered to be made up of normal 128Bx32 Y tiles, Thus
+ * the CCS pitch must be specified in multiples of 128 bytes.
+ *
+ * In reality the CCS tile appears to be a 64Bx64 Y tile, composed
+ * of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks.
+ * But that fact is not relevant unless the memory is accessed
+ * directly.
+ */
+#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4)
+#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
+
+/*
* Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
*
* Macroblocks are laid in a Z-shape, and each pixel data is following the
@@ -229,4 +338,290 @@
*/
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+/*
+ * Qualcomm Compressed Format
+ *
+ * Refers to a compressed variant of the base format that is compressed.
+ * Implementation may be platform and base-format specific.
+ *
+ * Each macrotile consists of m x n (mostly 4 x 4) tiles.
+ * Pixel data pitch/stride is aligned with macrotile width.
+ * Pixel data height is aligned with macrotile height.
+ * Entire pixel data buffer is aligned with 4k(bytes).
+ */
+#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
+
+/* Vivante framebuffer modifiers */
+
+/*
+ * Vivante 4x4 tiling layout
+ *
+ * This is a simple tiled layout using tiles of 4x4 pixels in a row-major
+ * layout.
+ */
+#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1)
+
+/*
+ * Vivante 64x64 super-tiling layout
+ *
+ * This is a tiled layout using 64x64 pixel super-tiles, where each super-tile
+ * contains 8x4 groups of 2x4 tiles of 4x4 pixels (like above) each, all in row-
+ * major layout.
+ *
+ * For more information: see
+ * https://github.com/etnaviv/etna_viv/blob/master/doc/hardware.md#texture-tiling
+ */
+#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2)
+
+/*
+ * Vivante 4x4 tiling layout for dual-pipe
+ *
+ * Same as the 4x4 tiling layout, except every second 4x4 pixel tile starts at a
+ * different base address. Offsets from the base addresses are therefore halved
+ * compared to the non-split tiled layout.
+ */
+#define DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED fourcc_mod_code(VIVANTE, 3)
+
+/*
+ * Vivante 64x64 super-tiling layout for dual-pipe
+ *
+ * Same as the 64x64 super-tiling layout, except every second 4x4 pixel tile
+ * starts at a different base address. Offsets from the base addresses are
+ * therefore halved compared to the non-split super-tiled layout.
+ */
+#define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4)
+
+/* NVIDIA frame buffer modifiers */
+
+/*
+ * Tegra Tiled Layout, used by Tegra 2, 3 and 4.
+ *
+ * Pixels are arranged in simple tiles of 16 x 16 bytes.
+ */
+#define DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED fourcc_mod_code(NVIDIA, 1)
+
+/*
+ * 16Bx2 Block Linear layout, used by desktop GPUs, and Tegra K1 and later
+ *
+ * Pixels are arranged in 64x8 Groups Of Bytes (GOBs). GOBs are then stacked
+ * vertically by a power of 2 (1 to 32 GOBs) to form a block.
+ *
+ * Within a GOB, data is ordered as 16B x 2 lines sectors laid in Z-shape.
+ *
+ * Parameter 'v' is the log2 encoding of the number of GOBs stacked vertically.
+ * Valid values are:
+ *
+ * 0 == ONE_GOB
+ * 1 == TWO_GOBS
+ * 2 == FOUR_GOBS
+ * 3 == EIGHT_GOBS
+ * 4 == SIXTEEN_GOBS
+ * 5 == THIRTYTWO_GOBS
+ *
+ * Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format
+ * in full detail.
+ */
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(v) \
+ fourcc_mod_code(NVIDIA, 0x10 | ((v) & 0xf))
+
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB \
+ fourcc_mod_code(NVIDIA, 0x10)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB \
+ fourcc_mod_code(NVIDIA, 0x11)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB \
+ fourcc_mod_code(NVIDIA, 0x12)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB \
+ fourcc_mod_code(NVIDIA, 0x13)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB \
+ fourcc_mod_code(NVIDIA, 0x14)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB \
+ fourcc_mod_code(NVIDIA, 0x15)
+
+/*
+ * Some Broadcom modifiers take parameters, for example the number of
+ * vertical lines in the image. Reserve the lower 32 bits for modifier
+ * type, and the next 24 bits for parameters. Top 8 bits are the
+ * vendor code.
+ */
+#define __fourcc_mod_broadcom_param_shift 8
+#define __fourcc_mod_broadcom_param_bits 48
+#define fourcc_mod_broadcom_code(val, params) \
+ fourcc_mod_code(BROADCOM, ((((__u64)params) << __fourcc_mod_broadcom_param_shift) | val))
+#define fourcc_mod_broadcom_param(m) \
+ ((int)(((m) >> __fourcc_mod_broadcom_param_shift) & \
+ ((1ULL << __fourcc_mod_broadcom_param_bits) - 1)))
+#define fourcc_mod_broadcom_mod(m) \
+ ((m) & ~(((1ULL << __fourcc_mod_broadcom_param_bits) - 1) << \
+ __fourcc_mod_broadcom_param_shift))
+
+/*
+ * Broadcom VC4 "T" format
+ *
+ * This is the primary layout that the V3D GPU can texture from (it
+ * can't do linear). The T format has:
+ *
+ * - 64b utiles of pixels in a raster-order grid according to cpp. It's 4x4
+ * pixels at 32 bit depth.
+ *
+ * - 1k subtiles made of a 4x4 raster-order grid of 64b utiles (so usually
+ * 16x16 pixels).
+ *
+ * - 4k tiles made of a 2x2 grid of 1k subtiles (so usually 32x32 pixels). On
+ * even 4k tile rows, they're arranged as (BL, TL, TR, BR), and on odd rows
+ * they're (TR, BR, BL, TL), where bottom left is start of memory.
+ *
+ * - an image made of 4k tiles in rows either left-to-right (even rows of 4k
+ * tiles) or right-to-left (odd rows of 4k tiles).
+ */
+#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1)
+
+/*
+ * Broadcom SAND format
+ *
+ * This is the native format that the H.264 codec block uses. For VC4
+ * HVS, it is only valid for H.264 (NV12/21) and RGBA modes.
+ *
+ * The image can be considered to be split into columns, and the
+ * columns are placed consecutively into memory. The width of those
+ * columns can be either 32, 64, 128, or 256 pixels, but in practice
+ * only 128 pixel columns are used.
+ *
+ * The pitch between the start of each column is set to optimally
+ * switch between SDRAM banks. This is passed as the number of lines
+ * of column width in the modifier (we can't use the stride value due
+ * to various core checks that look at it , so you should set the
+ * stride to width*cpp).
+ *
+ * Note that the column height for this format modifier is the same
+ * for all of the planes, assuming that each column contains both Y
+ * and UV. Some SAND-using hardware stores UV in a separate tiled
+ * image from Y to reduce the column height, which is not supported
+ * with these modifiers.
+ */
+
+#define DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(v) \
+ fourcc_mod_broadcom_code(2, v)
+#define DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT(v) \
+ fourcc_mod_broadcom_code(3, v)
+#define DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(v) \
+ fourcc_mod_broadcom_code(4, v)
+#define DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT(v) \
+ fourcc_mod_broadcom_code(5, v)
+
+#define DRM_FORMAT_MOD_BROADCOM_SAND32 \
+ DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(0)
+#define DRM_FORMAT_MOD_BROADCOM_SAND64 \
+ DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT(0)
+#define DRM_FORMAT_MOD_BROADCOM_SAND128 \
+ DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(0)
+#define DRM_FORMAT_MOD_BROADCOM_SAND256 \
+ DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT(0)
+
+/* Broadcom UIF format
+ *
+ * This is the common format for the current Broadcom multimedia
+ * blocks, including V3D 3.x and newer, newer video codecs, and
+ * displays.
+ *
+ * The image consists of utiles (64b blocks), UIF blocks (2x2 utiles),
+ * and macroblocks (4x4 UIF blocks). Those 4x4 UIF block groups are
+ * stored in columns, with padding between the columns to ensure that
+ * moving from one column to the next doesn't hit the same SDRAM page
+ * bank.
+ *
+ * To calculate the padding, it is assumed that each hardware block
+ * and the software driving it knows the platform's SDRAM page size,
+ * number of banks, and XOR address, and that it's identical between
+ * all blocks using the format. This tiling modifier will use XOR as
+ * necessary to reduce the padding. If a hardware block can't do XOR,
+ * the assumption is that a no-XOR tiling modifier will be created.
+ */
+#define DRM_FORMAT_MOD_BROADCOM_UIF fourcc_mod_code(BROADCOM, 6)
+
+/*
+ * Arm Framebuffer Compression (AFBC) modifiers
+ *
+ * AFBC is a proprietary lossless image compression protocol and format.
+ * It provides fine-grained random access and minimizes the amount of data
+ * transferred between IP blocks.
+ *
+ * AFBC has several features which may be supported and/or used, which are
+ * represented using bits in the modifier. Not all combinations are valid,
+ * and different devices or use-cases may support different combinations.
+ */
+#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) fourcc_mod_code(ARM, __afbc_mode)
+
+/*
+ * AFBC superblock size
+ *
+ * Indicates the superblock size(s) used for the AFBC buffer. The buffer
+ * size (in pixels) must be aligned to a multiple of the superblock size.
+ * Four lowest significant bits(LSBs) are reserved for block size.
+ */
+#define AFBC_FORMAT_MOD_BLOCK_SIZE_MASK 0xf
+#define AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 (1ULL)
+#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 (2ULL)
+
+/*
+ * AFBC lossless colorspace transform
+ *
+ * Indicates that the buffer makes use of the AFBC lossless colorspace
+ * transform.
+ */
+#define AFBC_FORMAT_MOD_YTR (1ULL << 4)
+
+/*
+ * AFBC block-split
+ *
+ * Indicates that the payload of each superblock is split. The second
+ * half of the payload is positioned at a predefined offset from the start
+ * of the superblock payload.
+ */
+#define AFBC_FORMAT_MOD_SPLIT (1ULL << 5)
+
+/*
+ * AFBC sparse layout
+ *
+ * This flag indicates that the payload of each superblock must be stored at a
+ * predefined position relative to the other superblocks in the same AFBC
+ * buffer. This order is the same order used by the header buffer. In this mode
+ * each superblock is given the same amount of space as an uncompressed
+ * superblock of the particular format would require, rounding up to the next
+ * multiple of 128 bytes in size.
+ */
+#define AFBC_FORMAT_MOD_SPARSE (1ULL << 6)
+
+/*
+ * AFBC copy-block restrict
+ *
+ * Buffers with this flag must obey the copy-block restriction. The restriction
+ * is such that there are no copy-blocks referring across the border of 8x8
+ * blocks. For the subsampled data the 8x8 limitation is also subsampled.
+ */
+#define AFBC_FORMAT_MOD_CBR (1ULL << 7)
+
+/*
+ * AFBC tiled layout
+ *
+ * The tiled layout groups superblocks in 8x8 or 4x4 tiles, where all
+ * superblocks inside a tile are stored together in memory. 8x8 tiles are used
+ * for pixel formats up to and including 32 bpp while 4x4 tiles are used for
+ * larger bpp formats. The order between the tiles is scan line.
+ * When the tiled layout is used, the buffer size (in pixels) must be aligned
+ * to the tile size.
+ */
+#define AFBC_FORMAT_MOD_TILED (1ULL << 8)
+
+/*
+ * AFBC solid color blocks
+ *
+ * Indicates that the buffer makes use of solid-color blocks, whereby bandwidth
+ * can be reduced if a whole superblock is a single color.
+ */
+#define AFBC_FORMAT_MOD_SC (1ULL << 9)
+
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* DRM_FOURCC_H */
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 6708e2b7..d3e0fe31 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -38,16 +38,28 @@ extern "C" {
#define DRM_DISPLAY_MODE_LEN 32
#define DRM_PROP_NAME_LEN 32
-#define DRM_MODE_TYPE_BUILTIN (1<<0)
-#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
-#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN)
+#define DRM_MODE_TYPE_BUILTIN (1<<0) /* deprecated */
+#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) /* deprecated */
+#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN) /* deprecated */
#define DRM_MODE_TYPE_PREFERRED (1<<3)
-#define DRM_MODE_TYPE_DEFAULT (1<<4)
+#define DRM_MODE_TYPE_DEFAULT (1<<4) /* deprecated */
#define DRM_MODE_TYPE_USERDEF (1<<5)
#define DRM_MODE_TYPE_DRIVER (1<<6)
+#define DRM_MODE_TYPE_ALL (DRM_MODE_TYPE_PREFERRED | \
+ DRM_MODE_TYPE_USERDEF | \
+ DRM_MODE_TYPE_DRIVER)
+
/* Video mode flags */
-/* bit compatible with the xorg definitions. */
+/* bit compatible with the xrandr RR_ definitions (bits 0-13)
+ *
+ * ABI warning: Existing userspace really expects
+ * the mode flags to match the xrandr definitions. Any
+ * changes that don't match the xrandr definitions will
+ * likely need a new client cap or some other mechanism
+ * to avoid breaking existing userspace. This includes
+ * allocating new flags in the previously unused bits!
+ */
#define DRM_MODE_FLAG_PHSYNC (1<<0)
#define DRM_MODE_FLAG_NHSYNC (1<<1)
#define DRM_MODE_FLAG_PVSYNC (1<<2)
@@ -58,8 +70,8 @@ extern "C" {
#define DRM_MODE_FLAG_PCSYNC (1<<7)
#define DRM_MODE_FLAG_NCSYNC (1<<8)
#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
-#define DRM_MODE_FLAG_BCAST (1<<10)
-#define DRM_MODE_FLAG_PIXMUX (1<<11)
+#define DRM_MODE_FLAG_BCAST (1<<10) /* deprecated */
+#define DRM_MODE_FLAG_PIXMUX (1<<11) /* deprecated */
#define DRM_MODE_FLAG_DBLCLK (1<<12)
#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
/*
@@ -67,7 +79,7 @@ extern "C" {
* (define not exposed to user space).
*/
#define DRM_MODE_FLAG_3D_MASK (0x1f<<14)
-#define DRM_MODE_FLAG_3D_NONE (0<<14)
+#define DRM_MODE_FLAG_3D_NONE (0<<14)
#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14)
#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14)
#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14)
@@ -77,6 +89,46 @@ extern "C" {
#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14)
#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14)
+/* Picture aspect ratio options */
+#define DRM_MODE_PICTURE_ASPECT_NONE 0
+#define DRM_MODE_PICTURE_ASPECT_4_3 1
+#define DRM_MODE_PICTURE_ASPECT_16_9 2
+#define DRM_MODE_PICTURE_ASPECT_64_27 3
+#define DRM_MODE_PICTURE_ASPECT_256_135 4
+
+/* Content type options */
+#define DRM_MODE_CONTENT_TYPE_NO_DATA 0
+#define DRM_MODE_CONTENT_TYPE_GRAPHICS 1
+#define DRM_MODE_CONTENT_TYPE_PHOTO 2
+#define DRM_MODE_CONTENT_TYPE_CINEMA 3
+#define DRM_MODE_CONTENT_TYPE_GAME 4
+
+/* Aspect ratio flag bitmask (4 bits 22:19) */
+#define DRM_MODE_FLAG_PIC_AR_MASK (0x0F<<19)
+#define DRM_MODE_FLAG_PIC_AR_NONE \
+ (DRM_MODE_PICTURE_ASPECT_NONE<<19)
+#define DRM_MODE_FLAG_PIC_AR_4_3 \
+ (DRM_MODE_PICTURE_ASPECT_4_3<<19)
+#define DRM_MODE_FLAG_PIC_AR_16_9 \
+ (DRM_MODE_PICTURE_ASPECT_16_9<<19)
+#define DRM_MODE_FLAG_PIC_AR_64_27 \
+ (DRM_MODE_PICTURE_ASPECT_64_27<<19)
+#define DRM_MODE_FLAG_PIC_AR_256_135 \
+ (DRM_MODE_PICTURE_ASPECT_256_135<<19)
+
+#define DRM_MODE_FLAG_ALL (DRM_MODE_FLAG_PHSYNC | \
+ DRM_MODE_FLAG_NHSYNC | \
+ DRM_MODE_FLAG_PVSYNC | \
+ DRM_MODE_FLAG_NVSYNC | \
+ DRM_MODE_FLAG_INTERLACE | \
+ DRM_MODE_FLAG_DBLSCAN | \
+ DRM_MODE_FLAG_CSYNC | \
+ DRM_MODE_FLAG_PCSYNC | \
+ DRM_MODE_FLAG_NCSYNC | \
+ DRM_MODE_FLAG_HSKEW | \
+ DRM_MODE_FLAG_DBLCLK | \
+ DRM_MODE_FLAG_CLKDIV2 | \
+ DRM_MODE_FLAG_3D_MASK)
/* DPMS flags */
/* bit compatible with the xorg definitions. */
@@ -92,11 +144,6 @@ extern "C" {
#define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */
#define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */
-/* Picture aspect ratio options */
-#define DRM_MODE_PICTURE_ASPECT_NONE 0
-#define DRM_MODE_PICTURE_ASPECT_4_3 1
-#define DRM_MODE_PICTURE_ASPECT_16_9 2
-
/* Dithering mode options */
#define DRM_MODE_DITHERING_OFF 0
#define DRM_MODE_DITHERING_ON 1
@@ -107,13 +154,61 @@ extern "C" {
#define DRM_MODE_DIRTY_ON 1
#define DRM_MODE_DIRTY_ANNOTATE 2
-/* rotation property bits */
-#define DRM_ROTATE_0 0
-#define DRM_ROTATE_90 1
-#define DRM_ROTATE_180 2
-#define DRM_ROTATE_270 3
-#define DRM_REFLECT_X 4
-#define DRM_REFLECT_Y 5
+/* Link Status options */
+#define DRM_MODE_LINK_STATUS_GOOD 0
+#define DRM_MODE_LINK_STATUS_BAD 1
+
+/*
+ * DRM_MODE_ROTATE_<degrees>
+ *
+ * Signals that a drm plane is been rotated <degrees> degrees in counter
+ * clockwise direction.
+ *
+ * This define is provided as a convenience, looking up the property id
+ * using the name->prop id lookup is the preferred method.
+ */
+#define DRM_MODE_ROTATE_0 (1<<0)
+#define DRM_MODE_ROTATE_90 (1<<1)
+#define DRM_MODE_ROTATE_180 (1<<2)
+#define DRM_MODE_ROTATE_270 (1<<3)
+
+/*
+ * DRM_MODE_ROTATE_MASK
+ *
+ * Bitmask used to look for drm plane rotations.
+ */
+#define DRM_MODE_ROTATE_MASK (\
+ DRM_MODE_ROTATE_0 | \
+ DRM_MODE_ROTATE_90 | \
+ DRM_MODE_ROTATE_180 | \
+ DRM_MODE_ROTATE_270)
+
+/*
+ * DRM_MODE_REFLECT_<axis>
+ *
+ * Signals that the contents of a drm plane is reflected along the <axis> axis,
+ * in the same way as mirroring.
+ * See kerneldoc chapter "Plane Composition Properties" for more details.
+ *
+ * This define is provided as a convenience, looking up the property id
+ * using the name->prop id lookup is the preferred method.
+ */
+#define DRM_MODE_REFLECT_X (1<<4)
+#define DRM_MODE_REFLECT_Y (1<<5)
+
+/*
+ * DRM_MODE_REFLECT_MASK
+ *
+ * Bitmask used to look for drm plane reflections.
+ */
+#define DRM_MODE_REFLECT_MASK (\
+ DRM_MODE_REFLECT_X | \
+ DRM_MODE_REFLECT_Y)
+
+/* Content Protection Flags */
+#define DRM_MODE_CONTENT_PROTECTION_UNDESIRED 0
+#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1
+#define DRM_MODE_CONTENT_PROTECTION_ENABLED 2
struct drm_mode_modeinfo {
__u32 clock;
@@ -228,14 +323,16 @@ struct drm_mode_get_encoder {
/* This is for connectors with multiple signal types. */
/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
-#define DRM_MODE_SUBCONNECTOR_Automatic 0
-#define DRM_MODE_SUBCONNECTOR_Unknown 0
-#define DRM_MODE_SUBCONNECTOR_DVID 3
-#define DRM_MODE_SUBCONNECTOR_DVIA 4
-#define DRM_MODE_SUBCONNECTOR_Composite 5
-#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
-#define DRM_MODE_SUBCONNECTOR_Component 8
-#define DRM_MODE_SUBCONNECTOR_SCART 9
+enum drm_mode_subconnector {
+ DRM_MODE_SUBCONNECTOR_Automatic = 0,
+ DRM_MODE_SUBCONNECTOR_Unknown = 0,
+ DRM_MODE_SUBCONNECTOR_DVID = 3,
+ DRM_MODE_SUBCONNECTOR_DVIA = 4,
+ DRM_MODE_SUBCONNECTOR_Composite = 5,
+ DRM_MODE_SUBCONNECTOR_SVIDEO = 6,
+ DRM_MODE_SUBCONNECTOR_Component = 8,
+ DRM_MODE_SUBCONNECTOR_SCART = 9,
+};
#define DRM_MODE_CONNECTOR_Unknown 0
#define DRM_MODE_CONNECTOR_VGA 1
@@ -255,6 +352,7 @@ struct drm_mode_get_encoder {
#define DRM_MODE_CONNECTOR_VIRTUAL 15
#define DRM_MODE_CONNECTOR_DSI 16
#define DRM_MODE_CONNECTOR_DPI 17
+#define DRM_MODE_CONNECTOR_WRITEBACK 18
struct drm_mode_get_connector {
@@ -280,7 +378,7 @@ struct drm_mode_get_connector {
__u32 pad;
};
-#define DRM_MODE_PROP_PENDING (1<<0)
+#define DRM_MODE_PROP_PENDING (1<<0) /* deprecated, do not use */
#define DRM_MODE_PROP_RANGE (1<<1)
#define DRM_MODE_PROP_IMMUTABLE (1<<2)
#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
@@ -400,17 +498,20 @@ struct drm_mode_fb_cmd2 {
* offsets[1]. Note that offsets[0] will generally
* be 0 (but this is not required).
*
- * To accommodate tiled, compressed, etc formats, a per-plane
+ * To accommodate tiled, compressed, etc formats, a
* modifier can be specified. The default value of zero
* indicates "native" format as specified by the fourcc.
- * Vendor specific modifier token. This allows, for example,
- * different tiling/swizzling pattern on different planes.
- * See discussion above of DRM_FORMAT_MOD_xxx.
+ * Vendor specific modifier token. Note that even though
+ * it looks like we have a modifier per-plane, we in fact
+ * do not. The modifier for each plane must be identical.
+ * Thus all combinations of different data layouts for
+ * multi plane formats must be enumerated as separate
+ * modifiers.
*/
__u32 handles[4];
__u32 pitches[4]; /* pitch for each plane */
__u32 offsets[4]; /* offset of each plane */
- __u64 modifier[4]; /* ie, tiling, compressed (per plane) */
+ __u64 modifier[4]; /* ie, tiling, compress */
};
#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
@@ -512,8 +613,11 @@ struct drm_mode_crtc_lut {
};
struct drm_color_ctm {
- /* Conversion matrix in S31.32 format. */
- __s64 matrix[9];
+ /*
+ * Conversion matrix in S31.32 sign-magnitude
+ * (not two's complement!) format.
+ */
+ __u64 matrix[9];
};
struct drm_color_lut {
@@ -637,13 +741,6 @@ struct drm_mode_destroy_dumb {
DRM_MODE_ATOMIC_NONBLOCK |\
DRM_MODE_ATOMIC_ALLOW_MODESET)
-#define DRM_MODE_ATOMIC_FLAGS (\
- DRM_MODE_PAGE_FLIP_EVENT |\
- DRM_MODE_PAGE_FLIP_ASYNC |\
- DRM_MODE_ATOMIC_TEST_ONLY |\
- DRM_MODE_ATOMIC_NONBLOCK |\
- DRM_MODE_ATOMIC_ALLOW_MODESET)
-
struct drm_mode_atomic {
__u32 flags;
__u32 count_objs;
@@ -655,6 +752,56 @@ struct drm_mode_atomic {
__u64 user_data;
};
+struct drm_format_modifier_blob {
+#define FORMAT_BLOB_CURRENT 1
+ /* Version of this blob format */
+ __u32 version;
+
+ /* Flags */
+ __u32 flags;
+
+ /* Number of fourcc formats supported */
+ __u32 count_formats;
+
+ /* Where in this blob the formats exist (in bytes) */
+ __u32 formats_offset;
+
+ /* Number of drm_format_modifiers */
+ __u32 count_modifiers;
+
+ /* Where in this blob the modifiers exist (in bytes) */
+ __u32 modifiers_offset;
+
+ /* __u32 formats[] */
+ /* struct drm_format_modifier modifiers[] */
+};
+
+struct drm_format_modifier {
+ /* Bitmask of formats in get_plane format list this info applies to. The
+ * offset allows a sliding window of which 64 formats (bits).
+ *
+ * Some examples:
+ * In today's world with < 65 formats, and formats 0, and 2 are
+ * supported
+ * 0x0000000000000005
+ * ^-offset = 0, formats = 5
+ *
+ * If the number formats grew to 128, and formats 98-102 are
+ * supported with the modifier:
+ *
+ * 0x0000007c00000000 0000000000000000
+ * ^
+ * |__offset = 64, formats = 0x7c00000000
+ *
+ */
+ __u64 formats;
+ __u32 offset;
+ __u32 pad;
+
+ /* The modifier that applies to the >get_plane format list bitmask. */
+ __u64 modifier;
+};
+
/**
* Create a new 'blob' data property, copying length bytes from data pointer,
* and returning new blob ID.
@@ -675,6 +822,72 @@ struct drm_mode_destroy_blob {
__u32 blob_id;
};
+/**
+ * Lease mode resources, creating another drm_master.
+ */
+struct drm_mode_create_lease {
+ /** Pointer to array of object ids (__u32) */
+ __u64 object_ids;
+ /** Number of object ids */
+ __u32 object_count;
+ /** flags for new FD (O_CLOEXEC, etc) */
+ __u32 flags;
+
+ /** Return: unique identifier for lessee. */
+ __u32 lessee_id;
+ /** Return: file descriptor to new drm_master file */
+ __u32 fd;
+};
+
+/**
+ * List lesses from a drm_master
+ */
+struct drm_mode_list_lessees {
+ /** Number of lessees.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_lessees;
+ __u32 pad;
+
+ /** Pointer to lessees.
+ * pointer to __u64 array of lessee ids
+ */
+ __u64 lessees_ptr;
+};
+
+/**
+ * Get leased objects
+ */
+struct drm_mode_get_lease {
+ /** Number of leased objects.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_objects;
+ __u32 pad;
+
+ /** Pointer to objects.
+ * pointer to __u32 array of object ids
+ */
+ __u64 objects_ptr;
+};
+
+/**
+ * Revoke lease
+ */
+struct drm_mode_revoke_lease {
+ /** Unique ID of lessee
+ */
+ __u32 lessee_id;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/drm/drm_sarea.h b/include/drm/drm_sarea.h
index 502934ed..93025be8 100644
--- a/include/drm/drm_sarea.h
+++ b/include/drm/drm_sarea.h
@@ -34,6 +34,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* SAREA area needs to be at least a page */
#if defined(__alpha__)
#define SAREA_MAX 0x2000U
@@ -81,4 +85,8 @@ typedef struct drm_sarea_drawable drm_sarea_drawable_t;
typedef struct drm_sarea_frame drm_sarea_frame_t;
typedef struct drm_sarea drm_sarea_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* _DRM_SAREA_H_ */
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 5ebe0462..268b585f 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -86,6 +86,62 @@ enum i915_mocs_table_index {
I915_MOCS_CACHED,
};
+/*
+ * Different engines serve different roles, and there may be more than one
+ * engine serving each role. enum drm_i915_gem_engine_class provides a
+ * classification of the role of the engine, which may be used when requesting
+ * operations to be performed on a certain subset of engines, or for providing
+ * information about that group.
+ */
+enum drm_i915_gem_engine_class {
+ I915_ENGINE_CLASS_RENDER = 0,
+ I915_ENGINE_CLASS_COPY = 1,
+ I915_ENGINE_CLASS_VIDEO = 2,
+ I915_ENGINE_CLASS_VIDEO_ENHANCE = 3,
+
+ I915_ENGINE_CLASS_INVALID = -1
+};
+
+/**
+ * DOC: perf_events exposed by i915 through /sys/bus/event_sources/drivers/i915
+ *
+ */
+
+enum drm_i915_pmu_engine_sample {
+ I915_SAMPLE_BUSY = 0,
+ I915_SAMPLE_WAIT = 1,
+ I915_SAMPLE_SEMA = 2
+};
+
+#define I915_PMU_SAMPLE_BITS (4)
+#define I915_PMU_SAMPLE_MASK (0xf)
+#define I915_PMU_SAMPLE_INSTANCE_BITS (8)
+#define I915_PMU_CLASS_SHIFT \
+ (I915_PMU_SAMPLE_BITS + I915_PMU_SAMPLE_INSTANCE_BITS)
+
+#define __I915_PMU_ENGINE(class, instance, sample) \
+ ((class) << I915_PMU_CLASS_SHIFT | \
+ (instance) << I915_PMU_SAMPLE_BITS | \
+ (sample))
+
+#define I915_PMU_ENGINE_BUSY(class, instance) \
+ __I915_PMU_ENGINE(class, instance, I915_SAMPLE_BUSY)
+
+#define I915_PMU_ENGINE_WAIT(class, instance) \
+ __I915_PMU_ENGINE(class, instance, I915_SAMPLE_WAIT)
+
+#define I915_PMU_ENGINE_SEMA(class, instance) \
+ __I915_PMU_ENGINE(class, instance, I915_SAMPLE_SEMA)
+
+#define __I915_PMU_OTHER(x) (__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x))
+
+#define I915_PMU_ACTUAL_FREQUENCY __I915_PMU_OTHER(0)
+#define I915_PMU_REQUESTED_FREQUENCY __I915_PMU_OTHER(1)
+#define I915_PMU_INTERRUPTS __I915_PMU_OTHER(2)
+#define I915_PMU_RC6_RESIDENCY __I915_PMU_OTHER(3)
+
+#define I915_PMU_LAST I915_PMU_RC6_RESIDENCY
+
/* Each region is a minimum of 16k, and there are at most 255 of them.
*/
#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use
@@ -260,6 +316,9 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
#define DRM_I915_PERF_OPEN 0x36
+#define DRM_I915_PERF_ADD_CONFIG 0x37
+#define DRM_I915_PERF_REMOVE_CONFIG 0x38
+#define DRM_I915_QUERY 0x39
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -315,6 +374,9 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
+#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
+#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
+#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -393,10 +455,20 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_MIN_EU_IN_POOL 39
#define I915_PARAM_MMAP_GTT_VERSION 40
-/* Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution
+/*
+ * Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution
* priorities and the driver will attempt to execute batches in priority order.
+ * The param returns a capability bitmask, nonzero implies that the scheduler
+ * is enabled, with different features present according to the mask.
+ *
+ * The initial priority for each batch is supplied by the context and is
+ * controlled via I915_CONTEXT_PARAM_PRIORITY.
*/
#define I915_PARAM_HAS_SCHEDULER 41
+#define I915_SCHEDULER_CAP_ENABLED (1ul << 0)
+#define I915_SCHEDULER_CAP_PRIORITY (1ul << 1)
+#define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2)
+
#define I915_PARAM_HUC_STATUS 42
/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to opt-out of
@@ -412,6 +484,73 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_HAS_EXEC_FENCE 44
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to capture
+ * user specified bufffers for post-mortem debugging of GPU hangs. See
+ * EXEC_OBJECT_CAPTURE.
+ */
+#define I915_PARAM_HAS_EXEC_CAPTURE 45
+
+#define I915_PARAM_SLICE_MASK 46
+
+/* Assuming it's uniform for each slice, this queries the mask of subslices
+ * per-slice for this system.
+ */
+#define I915_PARAM_SUBSLICE_MASK 47
+
+/*
+ * Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying the batch buffer
+ * as the first execobject as opposed to the last. See I915_EXEC_BATCH_FIRST.
+ */
+#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48
+
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY.
+ */
+#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49
+
+/*
+ * Query whether every context (both per-file default and user created) is
+ * isolated (insofar as HW supports). If this parameter is not true, then
+ * freshly created contexts may inherit values from an existing context,
+ * rather than default HW values. If true, it also ensures (insofar as HW
+ * supports) that all state set by this context will not leak to any other
+ * context.
+ *
+ * As not every engine across every gen support contexts, the returned
+ * value reports the support of context isolation for individual engines by
+ * returning a bitmask of each engine class set to true if that class supports
+ * isolation.
+ */
+#define I915_PARAM_HAS_CONTEXT_ISOLATION 50
+
+/* Frequency of the command streamer timestamps given by the *_TIMESTAMP
+ * registers. This used to be fixed per platform but from CNL onwards, this
+ * might vary depending on the parts.
+ */
+#define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51
+
+/*
+ * Once upon a time we supposed that writes through the GGTT would be
+ * immediately in physical memory (once flushed out of the CPU path). However,
+ * on a few different processors and chipsets, this is not necessarily the case
+ * as the writes appear to be buffered internally. Thus a read of the backing
+ * storage (physical memory) via a different path (with different physical tags
+ * to the indirect write via the GGTT) will see stale values from before
+ * the GGTT write. Inside the kernel, we can for the most part keep track of
+ * the different read/write domains in use (e.g. set-domain), but the assumption
+ * of coherency is baked into the ABI, hence reporting its true state in this
+ * parameter.
+ *
+ * Reports true when writes via mmap_gtt are immediately visible following an
+ * lfence to flush the WCB.
+ *
+ * Reports false when writes via mmap_gtt are indeterminately delayed in an in
+ * internal buffer and are _not_ immediately visible to third parties accessing
+ * directly via mmap_cpu/mmap_wc. Use of mmap_gtt as part of an IPC
+ * communications channel when reporting false is strongly disadvised.
+ */
+#define I915_PARAM_MMAP_GTT_COHERENT 52
+
typedef struct drm_i915_getparam {
__s32 param;
/*
@@ -666,6 +805,8 @@ struct drm_i915_gem_relocation_entry {
#define I915_GEM_DOMAIN_VERTEX 0x00000020
/** GTT domain - aperture and scanout */
#define I915_GEM_DOMAIN_GTT 0x00000040
+/** WC domain - uncached access */
+#define I915_GEM_DOMAIN_WC 0x00000080
/** @} */
struct drm_i915_gem_exec_object {
@@ -773,8 +914,15 @@ struct drm_i915_gem_exec_object2 {
* I915_PARAM_HAS_EXEC_FENCE to order execbufs and execute them asynchronously.
*/
#define EXEC_OBJECT_ASYNC (1<<6)
+/* Request that the contents of this execobject be copied into the error
+ * state upon a GPU hang involving this batch for post-mortem debugging.
+ * These buffers are recorded in no particular order as "user" in
+ * /sys/class/drm/cardN/error. Query I915_PARAM_HAS_EXEC_CAPTURE to see
+ * if the kernel supports this flag.
+ */
+#define EXEC_OBJECT_CAPTURE (1<<7)
/* All remaining bits are MBZ and RESERVED FOR FUTURE USE */
-#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_ASYNC<<1)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_CAPTURE<<1)
__u64 flags;
union {
@@ -784,6 +932,18 @@ struct drm_i915_gem_exec_object2 {
__u64 rsvd2;
};
+struct drm_i915_gem_exec_fence {
+ /**
+ * User's handle for a drm_syncobj to wait on or signal.
+ */
+ __u32 handle;
+
+#define I915_EXEC_FENCE_WAIT (1<<0)
+#define I915_EXEC_FENCE_SIGNAL (1<<1)
+#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1))
+ __u32 flags;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -798,7 +958,11 @@ struct drm_i915_gem_execbuffer2 {
__u32 DR1;
__u32 DR4;
__u32 num_cliprects;
- /** This is a struct drm_clip_rect *cliprects */
+ /**
+ * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
+ * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
+ * struct drm_i915_gem_exec_fence *fences.
+ */
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (7<<0)
#define I915_EXEC_DEFAULT (0<<0)
@@ -889,7 +1053,24 @@ struct drm_i915_gem_execbuffer2 {
*/
#define I915_EXEC_FENCE_OUT (1<<17)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_OUT<<1))
+/*
+ * Traditionally the execbuf ioctl has only considered the final element in
+ * the execobject[] to be the executable batch. Often though, the client
+ * will known the batch object prior to construction and being able to place
+ * it into the execobject[] array first can simplify the relocation tracking.
+ * Setting I915_EXEC_BATCH_FIRST tells execbuf to use element 0 of the
+ * execobject[] as the * batch instead (the default is to use the last
+ * element).
+ */
+#define I915_EXEC_BATCH_FIRST (1<<18)
+
+/* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr
+ * define an array of i915_gem_exec_fence structures which specify a set of
+ * dma fences to wait upon or signal.
+ */
+#define I915_EXEC_FENCE_ARRAY (1<<19)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
@@ -1201,7 +1382,9 @@ struct drm_intel_overlay_attrs {
* active on a given plane.
*/
-#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */
+#define I915_SET_COLORKEY_NONE (1<<0) /* Deprecated. Instead set
+ * flags==0 to disable colorkeying.
+ */
#define I915_SET_COLORKEY_DESTINATION (1<<1)
#define I915_SET_COLORKEY_SOURCE (1<<2)
struct drm_intel_sprite_colorkey {
@@ -1239,14 +1422,16 @@ struct drm_i915_reg_read {
* be specified
*/
__u64 offset;
+#define I915_REG_READ_8B_WA (1ul << 0)
+
__u64 val; /* Return value */
};
/* Known registers:
*
* Render engine timestamp - 0x2358 + 64bit - gen7+
* - Note this register returns an invalid value if using the default
- * single instruction 8byte read, in order to workaround that use
- * offset (0x2538 | 1) instead.
+ * single instruction 8byte read, in order to workaround that pass
+ * flag I915_REG_READ_8B_WA in offset field.
*
*/
@@ -1289,17 +1474,26 @@ struct drm_i915_gem_context_param {
#define I915_CONTEXT_PARAM_GTT_SIZE 0x3
#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
#define I915_CONTEXT_PARAM_BANNABLE 0x5
+#define I915_CONTEXT_PARAM_PRIORITY 0x6
+#define I915_CONTEXT_MAX_USER_PRIORITY 1023 /* inclusive */
+#define I915_CONTEXT_DEFAULT_PRIORITY 0
+#define I915_CONTEXT_MIN_USER_PRIORITY -1023 /* inclusive */
__u64 value;
};
enum drm_i915_oa_format {
- I915_OA_FORMAT_A13 = 1,
- I915_OA_FORMAT_A29,
- I915_OA_FORMAT_A13_B8_C8,
- I915_OA_FORMAT_B4_C8,
- I915_OA_FORMAT_A45_B8_C8,
- I915_OA_FORMAT_B4_C8_A16,
- I915_OA_FORMAT_C4_B8,
+ I915_OA_FORMAT_A13 = 1, /* HSW only */
+ I915_OA_FORMAT_A29, /* HSW only */
+ I915_OA_FORMAT_A13_B8_C8, /* HSW only */
+ I915_OA_FORMAT_B4_C8, /* HSW only */
+ I915_OA_FORMAT_A45_B8_C8, /* HSW only */
+ I915_OA_FORMAT_B4_C8_A16, /* HSW only */
+ I915_OA_FORMAT_C4_B8, /* HSW+ */
+
+ /* Gen8+ */
+ I915_OA_FORMAT_A12,
+ I915_OA_FORMAT_A12_B8_C8,
+ I915_OA_FORMAT_A32u40_A4u32_B8_C8,
I915_OA_FORMAT_MAX /* non-ABI */
};
@@ -1424,6 +1618,127 @@ enum drm_i915_perf_record_type {
DRM_I915_PERF_RECORD_MAX /* non-ABI */
};
+/**
+ * Structure to upload perf dynamic configuration into the kernel.
+ */
+struct drm_i915_perf_oa_config {
+ /** String formatted like "%08x-%04x-%04x-%04x-%012x" */
+ char uuid[36];
+
+ __u32 n_mux_regs;
+ __u32 n_boolean_regs;
+ __u32 n_flex_regs;
+
+ /*
+ * These fields are pointers to tuples of u32 values (register address,
+ * value). For example the expected length of the buffer pointed by
+ * mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs).
+ */
+ __u64 mux_regs_ptr;
+ __u64 boolean_regs_ptr;
+ __u64 flex_regs_ptr;
+};
+
+struct drm_i915_query_item {
+ __u64 query_id;
+#define DRM_I915_QUERY_TOPOLOGY_INFO 1
+
+ /*
+ * When set to zero by userspace, this is filled with the size of the
+ * data to be written at the data_ptr pointer. The kernel sets this
+ * value to a negative value to signal an error on a particular query
+ * item.
+ */
+ __s32 length;
+
+ /*
+ * Unused for now. Must be cleared to zero.
+ */
+ __u32 flags;
+
+ /*
+ * Data will be written at the location pointed by data_ptr when the
+ * value of length matches the length of the data to be written by the
+ * kernel.
+ */
+ __u64 data_ptr;
+};
+
+struct drm_i915_query {
+ __u32 num_items;
+
+ /*
+ * Unused for now. Must be cleared to zero.
+ */
+ __u32 flags;
+
+ /*
+ * This points to an array of num_items drm_i915_query_item structures.
+ */
+ __u64 items_ptr;
+};
+
+/*
+ * Data written by the kernel with query DRM_I915_QUERY_TOPOLOGY_INFO :
+ *
+ * data: contains the 3 pieces of information :
+ *
+ * - the slice mask with one bit per slice telling whether a slice is
+ * available. The availability of slice X can be queried with the following
+ * formula :
+ *
+ * (data[X / 8] >> (X % 8)) & 1
+ *
+ * - the subslice mask for each slice with one bit per subslice telling
+ * whether a subslice is available. The availability of subslice Y in slice
+ * X can be queried with the following formula :
+ *
+ * (data[subslice_offset +
+ * X * subslice_stride +
+ * Y / 8] >> (Y % 8)) & 1
+ *
+ * - the EU mask for each subslice in each slice with one bit per EU telling
+ * whether an EU is available. The availability of EU Z in subslice Y in
+ * slice X can be queried with the following formula :
+ *
+ * (data[eu_offset +
+ * (X * max_subslices + Y) * eu_stride +
+ * Z / 8] >> (Z % 8)) & 1
+ */
+struct drm_i915_query_topology_info {
+ /*
+ * Unused for now. Must be cleared to zero.
+ */
+ __u16 flags;
+
+ __u16 max_slices;
+ __u16 max_subslices;
+ __u16 max_eus_per_subslice;
+
+ /*
+ * Offset in data[] at which the subslice masks are stored.
+ */
+ __u16 subslice_offset;
+
+ /*
+ * Stride at which each of the subslice masks for each slice are
+ * stored.
+ */
+ __u16 subslice_stride;
+
+ /*
+ * Offset in data[] at which the EU masks are stored.
+ */
+ __u16 eu_offset;
+
+ /*
+ * Stride at which each of the EU masks for each subslice are stored.
+ */
+ __u16 eu_stride;
+
+ __u8 data[];
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h
index b630e8fa..79300111 100644
--- a/include/drm/mga_drm.h
+++ b/include/drm/mga_drm.h
@@ -37,6 +37,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (mga_sarea.h)
*/
@@ -107,7 +111,7 @@
*/
#define MGA_NR_SAREA_CLIPRECTS 8
-/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+/* 2 heaps (1 for card, 1 for agp), each divided into up to 128
* regions, subject to a minimum region size of (1<<16) == 64k.
*
* Clients may subdivide regions internally, but when sharing between
@@ -248,7 +252,7 @@ typedef struct _drm_mga_sarea {
#define DRM_MGA_DMA_BOOTSTRAP 0x0c
#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
-#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
+#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, struct drm_lock)
#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET)
#define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t)
@@ -416,4 +420,8 @@ typedef struct drm_mga_getparam {
void *value;
} drm_mga_getparam_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/freedreno/msm/msm_drm.h b/include/drm/msm_drm.h
index ed4c8d47..c06d0a5b 100644
--- a/freedreno/msm/msm_drm.h
+++ b/include/drm/msm_drm.h
@@ -25,7 +25,6 @@
#ifndef __MSM_DRM_H__
#define __MSM_DRM_H__
-#include <stddef.h>
#include "drm.h"
#if defined(__cplusplus)
@@ -73,6 +72,8 @@ struct drm_msm_timespec {
#define MSM_PARAM_CHIP_ID 0x03
#define MSM_PARAM_MAX_FREQ 0x04
#define MSM_PARAM_TIMESTAMP 0x05
+#define MSM_PARAM_GMEM_BASE 0x06
+#define MSM_PARAM_NR_RINGS 0x07
struct drm_msm_param {
__u32 pipe; /* in, MSM_PIPE_x */
@@ -104,10 +105,14 @@ struct drm_msm_gem_new {
__u32 handle; /* out */
};
+#define MSM_INFO_IOVA 0x01
+
+#define MSM_INFO_FLAGS (MSM_INFO_IOVA)
+
struct drm_msm_gem_info {
__u32 handle; /* in */
- __u32 pad;
- __u64 offset; /* out, offset to pass to mmap() */
+ __u32 flags; /* in - combination of MSM_INFO_* flags */
+ __u64 offset; /* out, mmap() offset or iova */
};
#define MSM_PREP_READ 0x01
@@ -167,7 +172,7 @@ struct drm_msm_gem_submit_cmd {
__u32 size; /* in, cmdstream size */
__u32 pad;
__u32 nr_relocs; /* in, number of submit_reloc's */
- __u64 __user relocs; /* in, ptr to array of submit_reloc's */
+ __u64 relocs; /* in, ptr to array of submit_reloc's */
};
/* Each buffer referenced elsewhere in the cmdstream submit (ie. the
@@ -196,10 +201,12 @@ struct drm_msm_gem_submit_bo {
#define MSM_SUBMIT_NO_IMPLICIT 0x80000000 /* disable implicit sync */
#define MSM_SUBMIT_FENCE_FD_IN 0x40000000 /* enable input fence_fd */
#define MSM_SUBMIT_FENCE_FD_OUT 0x20000000 /* enable output fence_fd */
+#define MSM_SUBMIT_SUDO 0x10000000 /* run submitted cmds from RB */
#define MSM_SUBMIT_FLAGS ( \
MSM_SUBMIT_NO_IMPLICIT | \
MSM_SUBMIT_FENCE_FD_IN | \
MSM_SUBMIT_FENCE_FD_OUT | \
+ MSM_SUBMIT_SUDO | \
0)
/* Each cmdstream submit consists of a table of buffers involved, and
@@ -211,9 +218,10 @@ struct drm_msm_gem_submit {
__u32 fence; /* out */
__u32 nr_bos; /* in, number of submit_bo's */
__u32 nr_cmds; /* in, number of submit_cmd's */
- __u64 __user bos; /* in, ptr to array of submit_bo's */
- __u64 __user cmds; /* in, ptr to array of submit_cmd's */
+ __u64 bos; /* in, ptr to array of submit_bo's */
+ __u64 cmds; /* in, ptr to array of submit_cmd's */
__s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */
+ __u32 queueid; /* in, submitqueue id */
};
/* The normal way to synchronize with the GPU is just to CPU_PREP on
@@ -227,6 +235,7 @@ struct drm_msm_wait_fence {
__u32 fence; /* in */
__u32 pad;
struct drm_msm_timespec timeout; /* in */
+ __u32 queueid; /* in, submitqueue id */
};
/* madvise provides a way to tell the kernel in case a buffers contents
@@ -250,6 +259,20 @@ struct drm_msm_gem_madvise {
__u32 retained; /* out, whether backing store still exists */
};
+/*
+ * Draw queues allow the user to set specific submission parameter. Command
+ * submissions specify a specific submitqueue to use. ID 0 is reserved for
+ * backwards compatibility as a "default" submitqueue
+ */
+
+#define MSM_SUBMITQUEUE_FLAGS (0)
+
+struct drm_msm_submitqueue {
+ __u32 flags; /* in, MSM_SUBMITQUEUE_x */
+ __u32 prio; /* in, Priority level */
+ __u32 id; /* out, identifier */
+};
+
#define DRM_MSM_GET_PARAM 0x00
/* placeholder:
#define DRM_MSM_SET_PARAM 0x01
@@ -261,7 +284,11 @@ struct drm_msm_gem_madvise {
#define DRM_MSM_GEM_SUBMIT 0x06
#define DRM_MSM_WAIT_FENCE 0x07
#define DRM_MSM_GEM_MADVISE 0x08
-#define DRM_MSM_NUM_IOCTLS 0x09
+/* placeholder:
+#define DRM_MSM_GEM_SVM_NEW 0x09
+ */
+#define DRM_MSM_SUBMITQUEUE_NEW 0x0A
+#define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B
#define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
#define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
@@ -271,6 +298,8 @@ struct drm_msm_gem_madvise {
#define DRM_IOCTL_MSM_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit)
#define DRM_IOCTL_MSM_WAIT_FENCE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence)
#define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32)
#if defined(__cplusplus)
}
diff --git a/include/drm/nouveau_class.h b/include/drm/nouveau_class.h
deleted file mode 100644
index 8d63877a..00000000
--- a/include/drm/nouveau_class.h
+++ /dev/null
@@ -1,651 +0,0 @@
-#ifndef __NVIF_CLASS_H__
-#define __NVIF_CLASS_H__
-
-/*******************************************************************************
- * class identifiers
- ******************************************************************************/
-
-/* the below match nvidia-assigned (either in hw, or sw) class numbers */
-#define NV_DEVICE 0x00000080
-
-#define NV_DMA_FROM_MEMORY 0x00000002
-#define NV_DMA_TO_MEMORY 0x00000003
-#define NV_DMA_IN_MEMORY 0x0000003d
-
-#define FERMI_TWOD_A 0x0000902d
-
-#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x0000903d
-
-#define KEPLER_INLINE_TO_MEMORY_A 0x0000a040
-#define KEPLER_INLINE_TO_MEMORY_B 0x0000a140
-
-#define NV04_DISP 0x00000046
-
-#define NV03_CHANNEL_DMA 0x0000006b
-#define NV10_CHANNEL_DMA 0x0000006e
-#define NV17_CHANNEL_DMA 0x0000176e
-#define NV40_CHANNEL_DMA 0x0000406e
-#define NV50_CHANNEL_DMA 0x0000506e
-#define G82_CHANNEL_DMA 0x0000826e
-
-#define NV50_CHANNEL_GPFIFO 0x0000506f
-#define G82_CHANNEL_GPFIFO 0x0000826f
-#define FERMI_CHANNEL_GPFIFO 0x0000906f
-#define KEPLER_CHANNEL_GPFIFO_A 0x0000a06f
-#define MAXWELL_CHANNEL_GPFIFO_A 0x0000b06f
-
-#define NV50_DISP 0x00005070
-#define G82_DISP 0x00008270
-#define GT200_DISP 0x00008370
-#define GT214_DISP 0x00008570
-#define GT206_DISP 0x00008870
-#define GF110_DISP 0x00009070
-#define GK104_DISP 0x00009170
-#define GK110_DISP 0x00009270
-#define GM107_DISP 0x00009470
-#define GM204_DISP 0x00009570
-
-#define NV50_DISP_CURSOR 0x0000507a
-#define G82_DISP_CURSOR 0x0000827a
-#define GT214_DISP_CURSOR 0x0000857a
-#define GF110_DISP_CURSOR 0x0000907a
-#define GK104_DISP_CURSOR 0x0000917a
-
-#define NV50_DISP_OVERLAY 0x0000507b
-#define G82_DISP_OVERLAY 0x0000827b
-#define GT214_DISP_OVERLAY 0x0000857b
-#define GF110_DISP_OVERLAY 0x0000907b
-#define GK104_DISP_OVERLAY 0x0000917b
-
-#define NV50_DISP_BASE_CHANNEL_DMA 0x0000507c
-#define G82_DISP_BASE_CHANNEL_DMA 0x0000827c
-#define GT200_DISP_BASE_CHANNEL_DMA 0x0000837c
-#define GT214_DISP_BASE_CHANNEL_DMA 0x0000857c
-#define GF110_DISP_BASE_CHANNEL_DMA 0x0000907c
-#define GK104_DISP_BASE_CHANNEL_DMA 0x0000917c
-#define GK110_DISP_BASE_CHANNEL_DMA 0x0000927c
-
-#define NV50_DISP_CORE_CHANNEL_DMA 0x0000507d
-#define G82_DISP_CORE_CHANNEL_DMA 0x0000827d
-#define GT200_DISP_CORE_CHANNEL_DMA 0x0000837d
-#define GT214_DISP_CORE_CHANNEL_DMA 0x0000857d
-#define GT206_DISP_CORE_CHANNEL_DMA 0x0000887d
-#define GF110_DISP_CORE_CHANNEL_DMA 0x0000907d
-#define GK104_DISP_CORE_CHANNEL_DMA 0x0000917d
-#define GK110_DISP_CORE_CHANNEL_DMA 0x0000927d
-#define GM107_DISP_CORE_CHANNEL_DMA 0x0000947d
-#define GM204_DISP_CORE_CHANNEL_DMA 0x0000957d
-
-#define NV50_DISP_OVERLAY_CHANNEL_DMA 0x0000507e
-#define G82_DISP_OVERLAY_CHANNEL_DMA 0x0000827e
-#define GT200_DISP_OVERLAY_CHANNEL_DMA 0x0000837e
-#define GT214_DISP_OVERLAY_CHANNEL_DMA 0x0000857e
-#define GF110_DISP_OVERLAY_CONTROL_DMA 0x0000907e
-#define GK104_DISP_OVERLAY_CONTROL_DMA 0x0000917e
-
-#define FERMI_A 0x00009097
-#define FERMI_B 0x00009197
-#define FERMI_C 0x00009297
-
-#define KEPLER_A 0x0000a097
-#define KEPLER_B 0x0000a197
-#define KEPLER_C 0x0000a297
-
-#define MAXWELL_A 0x0000b097
-#define MAXWELL_B 0x0000b197
-
-#define FERMI_COMPUTE_A 0x000090c0
-#define FERMI_COMPUTE_B 0x000091c0
-
-#define KEPLER_COMPUTE_A 0x0000a0c0
-#define KEPLER_COMPUTE_B 0x0000a1c0
-
-#define MAXWELL_COMPUTE_A 0x0000b0c0
-#define MAXWELL_COMPUTE_B 0x0000b1c0
-
-#define MAXWELL_DMA_COPY_A 0x0000b0b5
-
-/*******************************************************************************
- * client
- ******************************************************************************/
-
-#define NV_CLIENT_DEVLIST 0x00
-
-struct nv_client_devlist_v0 {
- __u8 version;
- __u8 count;
- __u8 pad02[6];
- __u64 device[];
-};
-
-
-/*******************************************************************************
- * device
- ******************************************************************************/
-
-struct nv_device_v0 {
- __u8 version;
- __u8 pad01[7];
- __u64 device; /* device identifier, ~0 for client default */
-#define NV_DEVICE_V0_DISABLE_IDENTIFY 0x0000000000000001ULL
-#define NV_DEVICE_V0_DISABLE_MMIO 0x0000000000000002ULL
-#define NV_DEVICE_V0_DISABLE_VBIOS 0x0000000000000004ULL
-#define NV_DEVICE_V0_DISABLE_CORE 0x0000000000000008ULL
-#define NV_DEVICE_V0_DISABLE_DISP 0x0000000000010000ULL
-#define NV_DEVICE_V0_DISABLE_FIFO 0x0000000000020000ULL
-#define NV_DEVICE_V0_DISABLE_GR 0x0000000100000000ULL
-#define NV_DEVICE_V0_DISABLE_MPEG 0x0000000200000000ULL
-#define NV_DEVICE_V0_DISABLE_ME 0x0000000400000000ULL
-#define NV_DEVICE_V0_DISABLE_VP 0x0000000800000000ULL
-#define NV_DEVICE_V0_DISABLE_CIPHER 0x0000001000000000ULL
-#define NV_DEVICE_V0_DISABLE_BSP 0x0000002000000000ULL
-#define NV_DEVICE_V0_DISABLE_MSPPP 0x0000004000000000ULL
-#define NV_DEVICE_V0_DISABLE_CE0 0x0000008000000000ULL
-#define NV_DEVICE_V0_DISABLE_CE1 0x0000010000000000ULL
-#define NV_DEVICE_V0_DISABLE_VIC 0x0000020000000000ULL
-#define NV_DEVICE_V0_DISABLE_MSENC 0x0000040000000000ULL
-#define NV_DEVICE_V0_DISABLE_CE2 0x0000080000000000ULL
-#define NV_DEVICE_V0_DISABLE_MSVLD 0x0000100000000000ULL
-#define NV_DEVICE_V0_DISABLE_SEC 0x0000200000000000ULL
-#define NV_DEVICE_V0_DISABLE_MSPDEC 0x0000400000000000ULL
- __u64 disable; /* disable particular subsystems */
- __u64 debug0; /* as above, but *internal* ids, and *NOT* ABI */
-};
-
-#define NV_DEVICE_V0_INFO 0x00
-#define NV_DEVICE_V0_ZCULL_INFO 0x01
-
-struct nv_device_info_v0 {
- __u8 version;
-#define NV_DEVICE_INFO_V0_IGP 0x00
-#define NV_DEVICE_INFO_V0_PCI 0x01
-#define NV_DEVICE_INFO_V0_AGP 0x02
-#define NV_DEVICE_INFO_V0_PCIE 0x03
-#define NV_DEVICE_INFO_V0_SOC 0x04
- __u8 platform;
- __u16 chipset; /* from NV_PMC_BOOT_0 */
- __u8 revision; /* from NV_PMC_BOOT_0 */
-#define NV_DEVICE_INFO_V0_TNT 0x01
-#define NV_DEVICE_INFO_V0_CELSIUS 0x02
-#define NV_DEVICE_INFO_V0_KELVIN 0x03
-#define NV_DEVICE_INFO_V0_RANKINE 0x04
-#define NV_DEVICE_INFO_V0_CURIE 0x05
-#define NV_DEVICE_INFO_V0_TESLA 0x06
-#define NV_DEVICE_INFO_V0_FERMI 0x07
-#define NV_DEVICE_INFO_V0_KEPLER 0x08
-#define NV_DEVICE_INFO_V0_MAXWELL 0x09
- __u8 family;
- __u8 pad06[2];
- __u64 ram_size;
- __u64 ram_user;
-};
-
-struct nv_device_zcull_info_v0 {
- __u8 version;
- __u8 pad03[3];
- __u32 image_size;
- __u32 width_align_pixels;
- __u32 height_align_pixels;
- __u32 pixel_squares_by_aliquots;
- __u32 aliquot_total;
- __u32 region_byte_multiplier;
- __u32 region_header_size;
- __u32 subregion_header_size;
- __u32 subregion_width_align_pixels;
- __u32 subregion_height_align_pixels;
- __u32 subregion_count;
-};
-
-/*******************************************************************************
- * context dma
- ******************************************************************************/
-
-struct nv_dma_v0 {
- __u8 version;
-#define NV_DMA_V0_TARGET_VM 0x00
-#define NV_DMA_V0_TARGET_VRAM 0x01
-#define NV_DMA_V0_TARGET_PCI 0x02
-#define NV_DMA_V0_TARGET_PCI_US 0x03
-#define NV_DMA_V0_TARGET_AGP 0x04
- __u8 target;
-#define NV_DMA_V0_ACCESS_VM 0x00
-#define NV_DMA_V0_ACCESS_RD 0x01
-#define NV_DMA_V0_ACCESS_WR 0x02
-#define NV_DMA_V0_ACCESS_RDWR (NV_DMA_V0_ACCESS_RD | NV_DMA_V0_ACCESS_WR)
- __u8 access;
- __u8 pad03[5];
- __u64 start;
- __u64 limit;
- /* ... chipset-specific class data */
-};
-
-struct nv50_dma_v0 {
- __u8 version;
-#define NV50_DMA_V0_PRIV_VM 0x00
-#define NV50_DMA_V0_PRIV_US 0x01
-#define NV50_DMA_V0_PRIV__S 0x02
- __u8 priv;
-#define NV50_DMA_V0_PART_VM 0x00
-#define NV50_DMA_V0_PART_256 0x01
-#define NV50_DMA_V0_PART_1KB 0x02
- __u8 part;
-#define NV50_DMA_V0_COMP_NONE 0x00
-#define NV50_DMA_V0_COMP_1 0x01
-#define NV50_DMA_V0_COMP_2 0x02
-#define NV50_DMA_V0_COMP_VM 0x03
- __u8 comp;
-#define NV50_DMA_V0_KIND_PITCH 0x00
-#define NV50_DMA_V0_KIND_VM 0x7f
- __u8 kind;
- __u8 pad05[3];
-};
-
-struct gf100_dma_v0 {
- __u8 version;
-#define GF100_DMA_V0_PRIV_VM 0x00
-#define GF100_DMA_V0_PRIV_US 0x01
-#define GF100_DMA_V0_PRIV__S 0x02
- __u8 priv;
-#define GF100_DMA_V0_KIND_PITCH 0x00
-#define GF100_DMA_V0_KIND_VM 0xff
- __u8 kind;
- __u8 pad03[5];
-};
-
-struct gf110_dma_v0 {
- __u8 version;
-#define GF110_DMA_V0_PAGE_LP 0x00
-#define GF110_DMA_V0_PAGE_SP 0x01
- __u8 page;
-#define GF110_DMA_V0_KIND_PITCH 0x00
-#define GF110_DMA_V0_KIND_VM 0xff
- __u8 kind;
- __u8 pad03[5];
-};
-
-
-/*******************************************************************************
- * perfmon
- ******************************************************************************/
-
-struct nvif_perfctr_v0 {
- __u8 version;
- __u8 pad01[1];
- __u16 logic_op;
- __u8 pad04[4];
- char name[4][64];
-};
-
-#define NVIF_PERFCTR_V0_QUERY 0x00
-#define NVIF_PERFCTR_V0_SAMPLE 0x01
-#define NVIF_PERFCTR_V0_READ 0x02
-
-struct nvif_perfctr_query_v0 {
- __u8 version;
- __u8 pad01[3];
- __u32 iter;
- char name[64];
-};
-
-struct nvif_perfctr_sample {
-};
-
-struct nvif_perfctr_read_v0 {
- __u8 version;
- __u8 pad01[7];
- __u32 ctr;
- __u32 clk;
-};
-
-
-/*******************************************************************************
- * device control
- ******************************************************************************/
-
-#define NVIF_CONTROL_PSTATE_INFO 0x00
-#define NVIF_CONTROL_PSTATE_ATTR 0x01
-#define NVIF_CONTROL_PSTATE_USER 0x02
-
-struct nvif_ustate {
- __s8 min;
- __s8 max;
-};
-
-struct nvif_control_pstate_info_v0 {
- __u8 version;
- __u8 count; /* out: number of power states */
-#define NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE (-1)
-#define NVIF_CONTROL_PSTATE_INFO_V0_USTATE_PERFMON (-2)
- struct {
- struct nvif_ustate dc; // pwrsrc == 0
- struct nvif_ustate ac; // pwrsrc == 1
- } ustate; /* out: target pstate index */
- __s8 pwrsrc; /* out: current power source */
-#define NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN (-1)
-#define NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_PERFMON (-2)
- __s8 pstate; /* out: current pstate index */
- __u8 pad06[2];
-};
-
-struct nvif_control_pstate_attr_v0 {
- __u8 version;
-#define NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT (-1)
- __s8 state; /* in: index of pstate to query
- * out: pstate identifier
- */
- __u8 index; /* in: index of attribute to query
- * out: index of next attribute, or 0 if no more
- */
- __u8 pad03[5];
- __u32 min;
- __u32 max;
- char name[32];
- char unit[16];
-};
-
-struct nvif_control_pstate_user_v0 {
- __u8 version;
-#define NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN (-1)
-#define NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON (-2)
- struct nvif_ustate ustate; /* in: pstate identifier */
- __s8 pwrsrc; /* in: target power source */
- __u8 pad03[5];
-};
-
-
-/*******************************************************************************
- * DMA FIFO channels
- ******************************************************************************/
-
-struct nv03_channel_dma_v0 {
- __u8 version;
- __u8 chid;
- __u8 pad02[2];
- __u32 pushbuf;
- __u64 offset;
-};
-
-#define G82_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
-
-/*******************************************************************************
- * GPFIFO channels
- ******************************************************************************/
-
-struct nv50_channel_gpfifo_v0 {
- __u8 version;
- __u8 chid;
- __u8 pad01[6];
- __u32 pushbuf;
- __u32 ilength;
- __u64 ioffset;
-};
-
-struct kepler_channel_gpfifo_a_v0 {
- __u8 version;
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR 0x01
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPDEC 0x02
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPPP 0x04
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSVLD 0x08
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0 0x10
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1 0x20
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_ENC 0x40
- __u8 engine;
- __u16 chid;
- __u8 pad04[4];
- __u32 pushbuf;
- __u32 ilength;
- __u64 ioffset;
-};
-
-#define CHANNEL_GPFIFO_ERROR_NOTIFIER_EEVENT 0x01
-
-/*******************************************************************************
- * legacy display
- ******************************************************************************/
-
-#define NV04_DISP_NTFY_VBLANK 0x00
-#define NV04_DISP_NTFY_CONN 0x01
-
-struct nv04_disp_mthd_v0 {
- __u8 version;
-#define NV04_DISP_SCANOUTPOS 0x00
- __u8 method;
- __u8 head;
- __u8 pad03[5];
-};
-
-struct nv04_disp_scanoutpos_v0 {
- __u8 version;
- __u8 pad01[7];
- __s64 time[2];
- __u16 vblanks;
- __u16 vblanke;
- __u16 vtotal;
- __u16 vline;
- __u16 hblanks;
- __u16 hblanke;
- __u16 htotal;
- __u16 hline;
-};
-
-/*******************************************************************************
- * display
- ******************************************************************************/
-
-#define NV50_DISP_MTHD 0x00
-
-struct nv50_disp_mthd_v0 {
- __u8 version;
-#define NV50_DISP_SCANOUTPOS 0x00
- __u8 method;
- __u8 head;
- __u8 pad03[5];
-};
-
-struct nv50_disp_mthd_v1 {
- __u8 version;
-#define NV50_DISP_MTHD_V1_DAC_PWR 0x10
-#define NV50_DISP_MTHD_V1_DAC_LOAD 0x11
-#define NV50_DISP_MTHD_V1_SOR_PWR 0x20
-#define NV50_DISP_MTHD_V1_SOR_HDA_ELD 0x21
-#define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22
-#define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT 0x23
-#define NV50_DISP_MTHD_V1_SOR_DP_PWR 0x24
-#define NV50_DISP_MTHD_V1_PIOR_PWR 0x30
- __u8 method;
- __u16 hasht;
- __u16 hashm;
- __u8 pad06[2];
-};
-
-struct nv50_disp_dac_pwr_v0 {
- __u8 version;
- __u8 state;
- __u8 data;
- __u8 vsync;
- __u8 hsync;
- __u8 pad05[3];
-};
-
-struct nv50_disp_dac_load_v0 {
- __u8 version;
- __u8 load;
- __u8 pad02[2];
- __u32 data;
-};
-
-struct nv50_disp_sor_pwr_v0 {
- __u8 version;
- __u8 state;
- __u8 pad02[6];
-};
-
-struct nv50_disp_sor_hda_eld_v0 {
- __u8 version;
- __u8 pad01[7];
- __u8 data[];
-};
-
-struct nv50_disp_sor_hdmi_pwr_v0 {
- __u8 version;
- __u8 state;
- __u8 max_ac_packet;
- __u8 rekey;
- __u8 pad04[4];
-};
-
-struct nv50_disp_sor_lvds_script_v0 {
- __u8 version;
- __u8 pad01[1];
- __u16 script;
- __u8 pad04[4];
-};
-
-struct nv50_disp_sor_dp_pwr_v0 {
- __u8 version;
- __u8 state;
- __u8 pad02[6];
-};
-
-struct nv50_disp_pior_pwr_v0 {
- __u8 version;
- __u8 state;
- __u8 type;
- __u8 pad03[5];
-};
-
-/* core */
-struct nv50_disp_core_channel_dma_v0 {
- __u8 version;
- __u8 pad01[3];
- __u32 pushbuf;
-};
-
-#define NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
-
-/* cursor immediate */
-struct nv50_disp_cursor_v0 {
- __u8 version;
- __u8 head;
- __u8 pad02[6];
-};
-
-#define NV50_DISP_CURSOR_V0_NTFY_UEVENT 0x00
-
-/* base */
-struct nv50_disp_base_channel_dma_v0 {
- __u8 version;
- __u8 pad01[2];
- __u8 head;
- __u32 pushbuf;
-};
-
-#define NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
-
-/* overlay */
-struct nv50_disp_overlay_channel_dma_v0 {
- __u8 version;
- __u8 pad01[2];
- __u8 head;
- __u32 pushbuf;
-};
-
-#define NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
-
-/* overlay immediate */
-struct nv50_disp_overlay_v0 {
- __u8 version;
- __u8 head;
- __u8 pad02[6];
-};
-
-#define NV50_DISP_OVERLAY_V0_NTFY_UEVENT 0x00
-
-/*******************************************************************************
- * fermi
- ******************************************************************************/
-
-#define FERMI_A_ZBC_COLOR 0x00
-#define FERMI_A_ZBC_DEPTH 0x01
-#define FERMI_A_ZCULL_BIND 0x02
-#define FERMI_A_ZBC_QUERY_COLOR 0x03
-#define FERMI_A_ZBC_QUERY_DEPTH 0x04
-#define FERMI_A_ZBC_QUERY_TABLE_SIZE 0x05
-
-struct fermi_a_zbc_color_v0 {
- __u8 version;
-#define FERMI_A_ZBC_COLOR_V0_FMT_ZERO 0x01
-#define FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE 0x02
-#define FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32 0x04
-#define FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16 0x08
-#define FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16 0x0c
-#define FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16 0x10
-#define FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16 0x14
-#define FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16 0x16
-#define FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8 0x18
-#define FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8 0x1c
-#define FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10 0x20
-#define FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10 0x24
-#define FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8 0x28
-#define FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8 0x2c
-#define FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8 0x30
-#define FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8 0x34
-#define FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8 0x38
-#define FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10 0x3c
-#define FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11 0x40
- __u8 format;
- __u8 index;
- __u8 pad03[5];
- __u32 ds[4];
- __u32 l2[4];
-};
-
-struct fermi_a_zbc_query_v0 {
- __u8 version;
- __u8 pad03[3];
- __u32 ds[4];
- __u32 l2[4];
- __u32 format;
- __u32 index;
- __u32 table_size;
-};
-
-struct fermi_a_zbc_depth_v0 {
- __u8 version;
-#define FERMI_A_ZBC_DEPTH_V0_FMT_FP32 0x01
- __u8 format;
- __u8 index;
- __u8 pad03[5];
- __u32 ds;
- __u32 l2;
-};
-
-struct fermi_a_zcull_bind_v0 {
- __u8 version;
- __u8 pad03[3];
-#define FERMI_A_ZCULL_BIND_MODE_GLOBAL 0x00
-#define FERMI_A_ZCULL_BIND_MODE_NO_CTXSW 0x01
-#define FERMI_A_ZCULL_BIND_MODE_SEPARATE_BUFFER 0x02
- __u32 mode;
- __u64 gpu_va;
-};
-
-#define KEPLER_SET_CHANNEL_PRIORITY 0x00
-#define KEPLER_SET_CHANNEL_TIMEOUT 0x01
-
-struct kepler_set_channel_priority_v0 {
- __u8 version;
-#define KEPLER_SET_CHANNEL_PRIORITY_LOW 0x00
-#define KEPLER_SET_CHANNEL_PRIORITY_MEDIUM 0x01
-#define KEPLER_SET_CHANNEL_PRIORITY_HIGH 0x02
- __u8 priority;
- __u8 pad03[6];
-};
-
-struct kepler_set_channel_timeout_v0 {
- __u8 version;
- __u8 pad03[3];
- __u32 timeout_ms;
-};
-
-#endif
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h
index 1372f533..d42105c8 100644
--- a/include/drm/nouveau_drm.h
+++ b/include/drm/nouveau_drm.h
@@ -27,13 +27,11 @@
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 16
-/* reserved object handles when using deprecated object APIs - these
- * are here so that libdrm can allow interoperability with the new
- * object APIs
- */
-#define NOUVEAU_ABI16_CLIENT 0xffffffff
-#define NOUVEAU_ABI16_DEVICE 0xdddddddd
-#define NOUVEAU_ABI16_CHAN(n) (0xcccc0000 | (n))
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
struct drm_nouveau_channel_alloc {
uint32_t fb_ctxdma_handle;
@@ -106,6 +104,7 @@ struct drm_nouveau_setparam {
#define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3)
#define NOUVEAU_GEM_DOMAIN_COHERENT (1 << 4)
+#define NOUVEAU_GEM_TILE_COMP 0x00030000 /* nv50-only */
#define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00
#define NOUVEAU_GEM_TILE_16BPP 0x00000001
#define NOUVEAU_GEM_TILE_32BPP 0x00000002
@@ -113,40 +112,34 @@ struct drm_nouveau_setparam {
#define NOUVEAU_GEM_TILE_NONCONTIG 0x00000008
struct drm_nouveau_gem_info {
- uint32_t handle;
- uint32_t domain;
- uint64_t size;
- uint64_t offset;
- uint64_t map_handle;
- uint32_t tile_mode;
- uint32_t tile_flags;
-};
-
-struct drm_nouveau_gem_set_tiling {
- uint32_t handle;
- uint32_t tile_mode;
- uint32_t tile_flags;
+ __u32 handle;
+ __u32 domain;
+ __u64 size;
+ __u64 offset;
+ __u64 map_handle;
+ __u32 tile_mode;
+ __u32 tile_flags;
};
struct drm_nouveau_gem_new {
struct drm_nouveau_gem_info info;
- uint32_t channel_hint;
- uint32_t align;
+ __u32 channel_hint;
+ __u32 align;
};
#define NOUVEAU_GEM_MAX_BUFFERS 1024
struct drm_nouveau_gem_pushbuf_bo_presumed {
- uint32_t valid;
- uint32_t domain;
- uint64_t offset;
+ __u32 valid;
+ __u32 domain;
+ __u64 offset;
};
struct drm_nouveau_gem_pushbuf_bo {
- uint64_t user_priv;
- uint32_t handle;
- uint32_t read_domains;
- uint32_t write_domains;
- uint32_t valid_domains;
+ __u64 user_priv;
+ __u32 handle;
+ __u32 read_domains;
+ __u32 write_domains;
+ __u32 valid_domains;
struct drm_nouveau_gem_pushbuf_bo_presumed presumed;
};
@@ -155,75 +148,47 @@ struct drm_nouveau_gem_pushbuf_bo {
#define NOUVEAU_GEM_RELOC_OR (1 << 2)
#define NOUVEAU_GEM_MAX_RELOCS 1024
struct drm_nouveau_gem_pushbuf_reloc {
- uint32_t reloc_bo_index;
- uint32_t reloc_bo_offset;
- uint32_t bo_index;
- uint32_t flags;
- uint32_t data;
- uint32_t vor;
- uint32_t tor;
+ __u32 reloc_bo_index;
+ __u32 reloc_bo_offset;
+ __u32 bo_index;
+ __u32 flags;
+ __u32 data;
+ __u32 vor;
+ __u32 tor;
};
#define NOUVEAU_GEM_MAX_PUSH 512
struct drm_nouveau_gem_pushbuf_push {
- uint32_t bo_index;
- uint32_t pad;
- uint64_t offset;
- uint64_t length;
+ __u32 bo_index;
+ __u32 pad;
+ __u64 offset;
+ __u64 length;
};
struct drm_nouveau_gem_pushbuf {
- uint32_t channel;
- uint32_t nr_buffers;
- uint64_t buffers;
- uint32_t nr_relocs;
- uint32_t nr_push;
- uint64_t relocs;
- uint64_t push;
- uint32_t suffix0;
- uint32_t suffix1;
- uint64_t vram_available;
- uint64_t gart_available;
-};
-
-#define NOUVEAU_GEM_PUSHBUF_2_FENCE_WAIT 0x00000001
-#define NOUVEAU_GEM_PUSHBUF_2_FENCE_EMIT 0x00000002
-struct drm_nouveau_gem_pushbuf_2 {
- uint32_t channel;
- uint32_t flags;
- uint32_t nr_push;
- uint32_t nr_buffers;
- int32_t fence; /* in/out, depends on flags */
- uint32_t pad;
- uint64_t push; /* in raw hw format */
- uint64_t buffers; /* ptr to drm_nouveau_gem_pushbuf_bo */
- uint64_t vram_available;
- uint64_t gart_available;
+ __u32 channel;
+ __u32 nr_buffers;
+ __u64 buffers;
+ __u32 nr_relocs;
+ __u32 nr_push;
+ __u64 relocs;
+ __u64 push;
+ __u32 suffix0;
+ __u32 suffix1;
+ __u64 vram_available;
+ __u64 gart_available;
};
#define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001
#define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002
#define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004
struct drm_nouveau_gem_cpu_prep {
- uint32_t handle;
- uint32_t flags;
+ __u32 handle;
+ __u32 flags;
};
struct drm_nouveau_gem_cpu_fini {
- uint32_t handle;
-};
-
-#define NOUVEAU_GEM_AS_SPARSE 0x00000001
-struct drm_nouveau_gem_as_alloc {
- uint64_t pages; /* in, page length */
- uint32_t page_size; /* in, byte page size */
- uint32_t flags; /* in, flags of address space */
- uint64_t align; /* in, requested alignment in bytes */
- uint64_t address; /* in/out, non-zero for fixed address allocation */
-};
-
-struct drm_nouveau_gem_as_free {
- uint64_t address; /* in, byte address */
+ __u32 handle;
};
enum nouveau_bus_type {
@@ -235,34 +200,6 @@ enum nouveau_bus_type {
struct drm_nouveau_sarea {
};
-#define NOUVEAU_GEM_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT 8
-#define NOUVEAU_GEM_CHANNEL_GR_ERROR_SW_NOTIFY 13
-#define NOUVEAU_GEM_CHANNEL_FIFO_ERROR_MMU_ERR_FLT 31
-#define NOUVEAU_GEM_CHANNEL_PBDMA_ERROR 32
-struct drm_nouveau_gem_set_error_notifier {
- uint32_t channel;
- uint32_t buffer;
- uint32_t offset; /* in bytes, u32-aligned */
-};
-
-struct drm_nouveau_gem_map {
- uint32_t handle;
- uint32_t domain;
- uint64_t offset;
- uint64_t delta;
- uint64_t length;
- uint32_t tile_mode;
- uint32_t tile_flags;
-};
-
-struct drm_nouveau_gem_unmap {
- uint32_t handle;
- uint32_t pad;
- uint64_t offset;
- uint64_t delta;
- uint64_t length;
-};
-
#define DRM_NOUVEAU_GETPARAM 0x00
#define DRM_NOUVEAU_SETPARAM 0x01
#define DRM_NOUVEAU_CHANNEL_ALLOC 0x02
@@ -277,14 +214,8 @@ struct drm_nouveau_gem_unmap {
#define DRM_NOUVEAU_GEM_CPU_FINI 0x43
#define DRM_NOUVEAU_GEM_INFO 0x44
-/* The ioctls below are marked as staging */
-#define DRM_NOUVEAU_GEM_SET_TILING 0x50
-#define DRM_NOUVEAU_GEM_PUSHBUF_2 0x51
-#define DRM_NOUVEAU_GEM_SET_INFO 0x52
-#define DRM_NOUVEAU_GEM_AS_ALLOC 0x53
-#define DRM_NOUVEAU_GEM_AS_FREE 0x54
-#define DRM_NOUVEAU_GEM_SET_ERROR_NOTIFIER 0x55
-#define DRM_NOUVEAU_GEM_MAP 0x56
-#define DRM_NOUVEAU_GEM_UNMAP 0x57
+#if defined(__cplusplus)
+}
+#endif
#endif /* __NOUVEAU_DRM_H__ */
diff --git a/include/drm/nouveau_ioctl.h b/include/drm/nouveau_ioctl.h
deleted file mode 100644
index 4cd8e323..00000000
--- a/include/drm/nouveau_ioctl.h
+++ /dev/null
@@ -1,128 +0,0 @@
-#ifndef __NVIF_IOCTL_H__
-#define __NVIF_IOCTL_H__
-
-struct nvif_ioctl_v0 {
- __u8 version;
-#define NVIF_IOCTL_V0_OWNER_NVIF 0x00
-#define NVIF_IOCTL_V0_OWNER_ANY 0xff
- __u8 owner;
-#define NVIF_IOCTL_V0_NOP 0x00
-#define NVIF_IOCTL_V0_SCLASS 0x01
-#define NVIF_IOCTL_V0_NEW 0x02
-#define NVIF_IOCTL_V0_DEL 0x03
-#define NVIF_IOCTL_V0_MTHD 0x04
-#define NVIF_IOCTL_V0_RD 0x05
-#define NVIF_IOCTL_V0_WR 0x06
-#define NVIF_IOCTL_V0_MAP 0x07
-#define NVIF_IOCTL_V0_UNMAP 0x08
-#define NVIF_IOCTL_V0_NTFY_NEW 0x09
-#define NVIF_IOCTL_V0_NTFY_DEL 0x0a
-#define NVIF_IOCTL_V0_NTFY_GET 0x0b
-#define NVIF_IOCTL_V0_NTFY_PUT 0x0c
- __u8 type;
- __u8 path_nr;
-#define NVIF_IOCTL_V0_ROUTE_NVIF 0x00
-#define NVIF_IOCTL_V0_ROUTE_HIDDEN 0xff
- __u8 pad04[3];
- __u8 route;
- __u64 token;
- __u32 path[8]; /* in reverse */
- __u8 data[]; /* ioctl data (below) */
-};
-
-struct nvif_ioctl_nop {
-};
-
-struct nvif_ioctl_sclass_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 count;
- __u8 pad02[6];
- __u32 oclass[];
-};
-
-struct nvif_ioctl_new_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 pad01[6];
- __u8 route;
- __u64 token;
- __u32 handle;
-/* these class numbers are made up by us, and not nvidia-assigned */
-#define NVIF_IOCTL_NEW_V0_PERFCTR 0x0000ffff
-#define NVIF_IOCTL_NEW_V0_CONTROL 0x0000fffe
- __u32 oclass;
- __u8 data[]; /* class data (class.h) */
-};
-
-struct nvif_ioctl_del {
-};
-
-struct nvif_ioctl_rd_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 size;
- __u8 pad02[2];
- __u32 data;
- __u64 addr;
-};
-
-struct nvif_ioctl_wr_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 size;
- __u8 pad02[2];
- __u32 data;
- __u64 addr;
-};
-
-struct nvif_ioctl_map_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 pad01[3];
- __u32 length;
- __u64 handle;
-};
-
-struct nvif_ioctl_unmap {
-};
-
-struct nvif_ioctl_ntfy_new_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 event;
- __u8 index;
- __u8 pad03[5];
- __u8 data[]; /* event request data (event.h) */
-};
-
-struct nvif_ioctl_ntfy_del_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 index;
- __u8 pad02[6];
-};
-
-struct nvif_ioctl_ntfy_get_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 index;
- __u8 pad02[6];
-};
-
-struct nvif_ioctl_ntfy_put_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 index;
- __u8 pad02[6];
-};
-
-struct nvif_ioctl_mthd_v0 {
- /* nvif_ioctl ... */
- __u8 version;
- __u8 method;
- __u8 pad02[6];
- __u8 data[]; /* method data (class.h) */
-};
-
-#endif
diff --git a/include/drm/qxl_drm.h b/include/drm/qxl_drm.h
index 1e331a86..880999d2 100644
--- a/include/drm/qxl_drm.h
+++ b/include/drm/qxl_drm.h
@@ -24,13 +24,16 @@
#ifndef QXL_DRM_H
#define QXL_DRM_H
-#include <stddef.h>
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* Please note that modifications to all structs defined here are
* subject to backwards-compatibility constraints.
*
- * Do not use pointers, use uint64_t instead for 32 bit / 64 bit user/kernel
+ * Do not use pointers, use __u64 instead for 32 bit / 64 bit user/kernel
* compatibility Keep fields aligned to their size
*/
@@ -48,14 +51,14 @@
#define DRM_QXL_ALLOC_SURF 0x06
struct drm_qxl_alloc {
- uint32_t size;
- uint32_t handle; /* 0 is an invalid handle */
+ __u32 size;
+ __u32 handle; /* 0 is an invalid handle */
};
struct drm_qxl_map {
- uint64_t offset; /* use for mmap system call */
- uint32_t handle;
- uint32_t pad;
+ __u64 offset; /* use for mmap system call */
+ __u32 handle;
+ __u32 pad;
};
/*
@@ -68,59 +71,58 @@ struct drm_qxl_map {
#define QXL_RELOC_TYPE_SURF 2
struct drm_qxl_reloc {
- uint64_t src_offset; /* offset into src_handle or src buffer */
- uint64_t dst_offset; /* offset in dest handle */
- uint32_t src_handle; /* dest handle to compute address from */
- uint32_t dst_handle; /* 0 if to command buffer */
- uint32_t reloc_type;
- uint32_t pad;
+ __u64 src_offset; /* offset into src_handle or src buffer */
+ __u64 dst_offset; /* offset in dest handle */
+ __u32 src_handle; /* dest handle to compute address from */
+ __u32 dst_handle; /* 0 if to command buffer */
+ __u32 reloc_type;
+ __u32 pad;
};
struct drm_qxl_command {
- uint64_t command; /* void* */
- uint64_t relocs; /* struct drm_qxl_reloc* */
- uint32_t type;
- uint32_t command_size;
- uint32_t relocs_num;
- uint32_t pad;
+ __u64 command; /* void* */
+ __u64 relocs; /* struct drm_qxl_reloc* */
+ __u32 type;
+ __u32 command_size;
+ __u32 relocs_num;
+ __u32 pad;
};
-/* XXX: call it drm_qxl_commands? */
struct drm_qxl_execbuffer {
- uint32_t flags; /* for future use */
- uint32_t commands_num;
- uint64_t commands; /* struct drm_qxl_command* */
+ __u32 flags; /* for future use */
+ __u32 commands_num;
+ __u64 commands; /* struct drm_qxl_command* */
};
struct drm_qxl_update_area {
- uint32_t handle;
- uint32_t top;
- uint32_t left;
- uint32_t bottom;
- uint32_t right;
- uint32_t pad;
+ __u32 handle;
+ __u32 top;
+ __u32 left;
+ __u32 bottom;
+ __u32 right;
+ __u32 pad;
};
#define QXL_PARAM_NUM_SURFACES 1 /* rom->n_surfaces */
#define QXL_PARAM_MAX_RELOCS 2
struct drm_qxl_getparam {
- uint64_t param;
- uint64_t value;
+ __u64 param;
+ __u64 value;
};
/* these are one bit values */
struct drm_qxl_clientcap {
- uint32_t index;
- uint32_t pad;
+ __u32 index;
+ __u32 pad;
};
struct drm_qxl_alloc_surf {
- uint32_t format;
- uint32_t width;
- uint32_t height;
- int32_t stride;
- uint32_t handle;
- uint32_t pad;
+ __u32 format;
+ __u32 width;
+ __u32 height;
+ __s32 stride;
+ __u32 handle;
+ __u32 pad;
};
#define DRM_IOCTL_QXL_ALLOC \
@@ -149,4 +151,8 @@ struct drm_qxl_alloc_surf {
DRM_IOWR(DRM_COMMAND_BASE + DRM_QXL_ALLOC_SURF,\
struct drm_qxl_alloc_surf)
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/include/drm/r128_drm.h b/include/drm/r128_drm.h
index ede78ff9..bf431a02 100644
--- a/include/drm/r128_drm.h
+++ b/include/drm/r128_drm.h
@@ -33,6 +33,12 @@
#ifndef __R128_DRM_H__
#define __R128_DRM_H__
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* WARNING: If you change any of these defines, make sure to change the
* defines in the X server file (r128_sarea.h)
*/
@@ -323,4 +329,8 @@ typedef struct drm_r128_getparam {
void *value;
} drm_r128_getparam_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
index f09cc04c..a1e385d6 100644
--- a/include/drm/radeon_drm.h
+++ b/include/drm/radeon_drm.h
@@ -797,9 +797,9 @@ typedef struct drm_radeon_surface_free {
#define RADEON_GEM_DOMAIN_VRAM 0x4
struct drm_radeon_gem_info {
- uint64_t gart_size;
- uint64_t vram_size;
- uint64_t vram_visible;
+ __u64 gart_size;
+ __u64 vram_size;
+ __u64 vram_visible;
};
#define RADEON_GEM_NO_BACKING_STORE (1 << 0)
@@ -811,11 +811,11 @@ struct drm_radeon_gem_info {
#define RADEON_GEM_NO_CPU_ACCESS (1 << 4)
struct drm_radeon_gem_create {
- uint64_t size;
- uint64_t alignment;
- uint32_t handle;
- uint32_t initial_domain;
- uint32_t flags;
+ __u64 size;
+ __u64 alignment;
+ __u32 handle;
+ __u32 initial_domain;
+ __u32 flags;
};
/*
@@ -829,10 +829,10 @@ struct drm_radeon_gem_create {
#define RADEON_GEM_USERPTR_REGISTER (1 << 3)
struct drm_radeon_gem_userptr {
- uint64_t addr;
- uint64_t size;
- uint32_t flags;
- uint32_t handle;
+ __u64 addr;
+ __u64 size;
+ __u32 flags;
+ __u32 handle;
};
#define RADEON_TILING_MACRO 0x1
@@ -855,72 +855,72 @@ struct drm_radeon_gem_userptr {
#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK 0xf
struct drm_radeon_gem_set_tiling {
- uint32_t handle;
- uint32_t tiling_flags;
- uint32_t pitch;
+ __u32 handle;
+ __u32 tiling_flags;
+ __u32 pitch;
};
struct drm_radeon_gem_get_tiling {
- uint32_t handle;
- uint32_t tiling_flags;
- uint32_t pitch;
+ __u32 handle;
+ __u32 tiling_flags;
+ __u32 pitch;
};
struct drm_radeon_gem_mmap {
- uint32_t handle;
- uint32_t pad;
- uint64_t offset;
- uint64_t size;
- uint64_t addr_ptr;
+ __u32 handle;
+ __u32 pad;
+ __u64 offset;
+ __u64 size;
+ __u64 addr_ptr;
};
struct drm_radeon_gem_set_domain {
- uint32_t handle;
- uint32_t read_domains;
- uint32_t write_domain;
+ __u32 handle;
+ __u32 read_domains;
+ __u32 write_domain;
};
struct drm_radeon_gem_wait_idle {
- uint32_t handle;
- uint32_t pad;
+ __u32 handle;
+ __u32 pad;
};
struct drm_radeon_gem_busy {
- uint32_t handle;
- uint32_t domain;
+ __u32 handle;
+ __u32 domain;
};
struct drm_radeon_gem_pread {
/** Handle for the object being read. */
- uint32_t handle;
- uint32_t pad;
+ __u32 handle;
+ __u32 pad;
/** Offset into the object to read from */
- uint64_t offset;
+ __u64 offset;
/** Length of data to read */
- uint64_t size;
+ __u64 size;
/** Pointer to write the data into. */
/* void *, but pointers are not 32/64 compatible */
- uint64_t data_ptr;
+ __u64 data_ptr;
};
struct drm_radeon_gem_pwrite {
/** Handle for the object being written to. */
- uint32_t handle;
- uint32_t pad;
+ __u32 handle;
+ __u32 pad;
/** Offset into the object to write to */
- uint64_t offset;
+ __u64 offset;
/** Length of data to write */
- uint64_t size;
+ __u64 size;
/** Pointer to read the data from. */
/* void *, but pointers are not 32/64 compatible */
- uint64_t data_ptr;
+ __u64 data_ptr;
};
/* Sets or returns a value associated with a buffer. */
struct drm_radeon_gem_op {
- uint32_t handle; /* buffer */
- uint32_t op; /* RADEON_GEM_OP_* */
- uint64_t value; /* input or return value */
+ __u32 handle; /* buffer */
+ __u32 op; /* RADEON_GEM_OP_* */
+ __u64 value; /* input or return value */
};
#define RADEON_GEM_OP_GET_INITIAL_DOMAIN 0
@@ -940,11 +940,11 @@ struct drm_radeon_gem_op {
#define RADEON_VM_PAGE_SNOOPED (1 << 4)
struct drm_radeon_gem_va {
- uint32_t handle;
- uint32_t operation;
- uint32_t vm_id;
- uint32_t flags;
- uint64_t offset;
+ __u32 handle;
+ __u32 operation;
+ __u32 vm_id;
+ __u32 flags;
+ __u64 offset;
};
#define RADEON_CHUNK_ID_RELOCS 0x01
@@ -966,29 +966,29 @@ struct drm_radeon_gem_va {
/* 0 = normal, + = higher priority, - = lower priority */
struct drm_radeon_cs_chunk {
- uint32_t chunk_id;
- uint32_t length_dw;
- uint64_t chunk_data;
+ __u32 chunk_id;
+ __u32 length_dw;
+ __u64 chunk_data;
};
/* drm_radeon_cs_reloc.flags */
#define RADEON_RELOC_PRIO_MASK (0xf << 0)
struct drm_radeon_cs_reloc {
- uint32_t handle;
- uint32_t read_domains;
- uint32_t write_domain;
- uint32_t flags;
+ __u32 handle;
+ __u32 read_domains;
+ __u32 write_domain;
+ __u32 flags;
};
struct drm_radeon_cs {
- uint32_t num_chunks;
- uint32_t cs_id;
- /* this points to uint64_t * which point to cs chunks */
- uint64_t chunks;
+ __u32 num_chunks;
+ __u32 cs_id;
+ /* this points to __u64 * which point to cs chunks */
+ __u64 chunks;
/* updates to the limits after this CS ioctl */
- uint64_t gart_limit;
- uint64_t vram_limit;
+ __u64 gart_limit;
+ __u64 vram_limit;
};
#define RADEON_INFO_DEVICE_ID 0x00
@@ -1047,9 +1047,9 @@ struct drm_radeon_cs {
#define RADEON_INFO_GPU_RESET_COUNTER 0x26
struct drm_radeon_info {
- uint32_t request;
- uint32_t pad;
- uint64_t value;
+ __u32 request;
+ __u32 pad;
+ __u64 value;
};
/* Those correspond to the tile index to use, this is to explicitly state
diff --git a/include/drm/savage_drm.h b/include/drm/savage_drm.h
index f7a75eff..1a91234e 100644
--- a/include/drm/savage_drm.h
+++ b/include/drm/savage_drm.h
@@ -26,10 +26,16 @@
#ifndef __SAVAGE_DRM_H__
#define __SAVAGE_DRM_H__
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
#ifndef __SAVAGE_SAREA_DEFINES__
#define __SAVAGE_SAREA_DEFINES__
-/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+/* 2 heaps (1 for card, 1 for agp), each divided into up to 128
* regions, subject to a minimum region size of (1<<16) == 64k.
*
* Clients may subdivide regions internally, but when sharing between
@@ -63,10 +69,10 @@ typedef struct _drm_savage_sarea {
#define DRM_SAVAGE_BCI_EVENT_EMIT 0x02
#define DRM_SAVAGE_BCI_EVENT_WAIT 0x03
-#define DRM_IOCTL_SAVAGE_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
-#define DRM_IOCTL_SAVAGE_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
-#define DRM_IOCTL_SAVAGE_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
-#define DRM_IOCTL_SAVAGE_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
+#define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
+#define DRM_IOCTL_SAVAGE_BCI_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
+#define DRM_IOCTL_SAVAGE_BCI_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
+#define DRM_IOCTL_SAVAGE_BCI_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
#define SAVAGE_DMA_PCI 1
#define SAVAGE_DMA_AGP 3
@@ -207,4 +213,8 @@ union drm_savage_cmd_header {
} clear1; /* SAVAGE_CMD_CLEAR data */
};
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/include/drm/sis_drm.h b/include/drm/sis_drm.h
index 30f7b382..8e51bb9a 100644
--- a/include/drm/sis_drm.h
+++ b/include/drm/sis_drm.h
@@ -27,6 +27,12 @@
#ifndef __SIS_DRM_H__
#define __SIS_DRM_H__
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* SiS specific ioctls */
#define NOT_USED_0_3
#define DRM_SIS_FB_ALLOC 0x04
@@ -64,4 +70,8 @@ typedef struct {
unsigned int offset, size;
} drm_sis_fb_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* __SIS_DRM_H__ */
diff --git a/include/drm/tegra_drm.h b/include/drm/tegra_drm.h
index 1be09c4b..6c07919c 100644
--- a/include/drm/tegra_drm.h
+++ b/include/drm/tegra_drm.h
@@ -1,194 +1,647 @@
/*
* Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
+ * 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:
*
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 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 _UAPI_TEGRA_DRM_H_
-#define _UAPI_TEGRA_DRM_H_
+#ifndef _TEGRA_DRM_H_
+#define _TEGRA_DRM_H_
-#include <drm/drm.h>
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0)
#define DRM_TEGRA_GEM_CREATE_BOTTOM_UP (1 << 1)
+/**
+ * struct drm_tegra_gem_create - parameters for the GEM object creation IOCTL
+ */
struct drm_tegra_gem_create {
+ /**
+ * @size:
+ *
+ * The size, in bytes, of the buffer object to be created.
+ */
__u64 size;
+
+ /**
+ * @flags:
+ *
+ * A bitmask of flags that influence the creation of GEM objects:
+ *
+ * DRM_TEGRA_GEM_CREATE_TILED
+ * Use the 16x16 tiling format for this buffer.
+ *
+ * DRM_TEGRA_GEM_CREATE_BOTTOM_UP
+ * The buffer has a bottom-up layout.
+ */
__u32 flags;
+
+ /**
+ * @handle:
+ *
+ * The handle of the created GEM object. Set by the kernel upon
+ * successful completion of the IOCTL.
+ */
__u32 handle;
};
+/**
+ * struct drm_tegra_gem_mmap - parameters for the GEM mmap IOCTL
+ */
struct drm_tegra_gem_mmap {
+ /**
+ * @handle:
+ *
+ * Handle of the GEM object to obtain an mmap offset for.
+ */
__u32 handle;
+
+ /**
+ * @pad:
+ *
+ * Structure padding that may be used in the future. Must be 0.
+ */
__u32 pad;
+
+ /**
+ * @offset:
+ *
+ * The mmap offset for the given GEM object. Set by the kernel upon
+ * successful completion of the IOCTL.
+ */
__u64 offset;
};
+/**
+ * struct drm_tegra_syncpt_read - parameters for the read syncpoint IOCTL
+ */
struct drm_tegra_syncpt_read {
+ /**
+ * @id:
+ *
+ * ID of the syncpoint to read the current value from.
+ */
__u32 id;
+
+ /**
+ * @value:
+ *
+ * The current syncpoint value. Set by the kernel upon successful
+ * completion of the IOCTL.
+ */
__u32 value;
};
+/**
+ * struct drm_tegra_syncpt_incr - parameters for the increment syncpoint IOCTL
+ */
struct drm_tegra_syncpt_incr {
+ /**
+ * @id:
+ *
+ * ID of the syncpoint to increment.
+ */
__u32 id;
+
+ /**
+ * @pad:
+ *
+ * Structure padding that may be used in the future. Must be 0.
+ */
__u32 pad;
};
+/**
+ * struct drm_tegra_syncpt_wait - parameters for the wait syncpoint IOCTL
+ */
struct drm_tegra_syncpt_wait {
+ /**
+ * @id:
+ *
+ * ID of the syncpoint to wait on.
+ */
__u32 id;
+
+ /**
+ * @thresh:
+ *
+ * Threshold value for which to wait.
+ */
__u32 thresh;
+
+ /**
+ * @timeout:
+ *
+ * Timeout, in milliseconds, to wait.
+ */
__u32 timeout;
+
+ /**
+ * @value:
+ *
+ * The new syncpoint value after the wait. Set by the kernel upon
+ * successful completion of the IOCTL.
+ */
__u32 value;
};
#define DRM_TEGRA_NO_TIMEOUT (0xffffffff)
+/**
+ * struct drm_tegra_open_channel - parameters for the open channel IOCTL
+ */
struct drm_tegra_open_channel {
+ /**
+ * @client:
+ *
+ * The client ID for this channel.
+ */
__u32 client;
+
+ /**
+ * @pad:
+ *
+ * Structure padding that may be used in the future. Must be 0.
+ */
__u32 pad;
+
+ /**
+ * @context:
+ *
+ * The application context of this channel. Set by the kernel upon
+ * successful completion of the IOCTL. This context needs to be passed
+ * to the DRM_TEGRA_CHANNEL_CLOSE or the DRM_TEGRA_SUBMIT IOCTLs.
+ */
__u64 context;
};
+/**
+ * struct drm_tegra_close_channel - parameters for the close channel IOCTL
+ */
struct drm_tegra_close_channel {
+ /**
+ * @context:
+ *
+ * The application context of this channel. This is obtained from the
+ * DRM_TEGRA_OPEN_CHANNEL IOCTL.
+ */
__u64 context;
};
+/**
+ * struct drm_tegra_get_syncpt - parameters for the get syncpoint IOCTL
+ */
struct drm_tegra_get_syncpt {
+ /**
+ * @context:
+ *
+ * The application context identifying the channel for which to obtain
+ * the syncpoint ID.
+ */
__u64 context;
+
+ /**
+ * @index:
+ *
+ * Index of the client syncpoint for which to obtain the ID.
+ */
__u32 index;
+
+ /**
+ * @id:
+ *
+ * The ID of the given syncpoint. Set by the kernel upon successful
+ * completion of the IOCTL.
+ */
__u32 id;
};
+/**
+ * struct drm_tegra_get_syncpt_base - parameters for the get wait base IOCTL
+ */
struct drm_tegra_get_syncpt_base {
+ /**
+ * @context:
+ *
+ * The application context identifying for which channel to obtain the
+ * wait base.
+ */
__u64 context;
+
+ /**
+ * @syncpt:
+ *
+ * ID of the syncpoint for which to obtain the wait base.
+ */
__u32 syncpt;
+
+ /**
+ * @id:
+ *
+ * The ID of the wait base corresponding to the client syncpoint. Set
+ * by the kernel upon successful completion of the IOCTL.
+ */
__u32 id;
};
+/**
+ * struct drm_tegra_syncpt - syncpoint increment operation
+ */
struct drm_tegra_syncpt {
+ /**
+ * @id:
+ *
+ * ID of the syncpoint to operate on.
+ */
__u32 id;
+
+ /**
+ * @incrs:
+ *
+ * Number of increments to perform for the syncpoint.
+ */
__u32 incrs;
};
+/**
+ * struct drm_tegra_cmdbuf - structure describing a command buffer
+ */
struct drm_tegra_cmdbuf {
+ /**
+ * @handle:
+ *
+ * Handle to a GEM object containing the command buffer.
+ */
__u32 handle;
+
+ /**
+ * @offset:
+ *
+ * Offset, in bytes, into the GEM object identified by @handle at
+ * which the command buffer starts.
+ */
__u32 offset;
+
+ /**
+ * @words:
+ *
+ * Number of 32-bit words in this command buffer.
+ */
__u32 words;
+
+ /**
+ * @pad:
+ *
+ * Structure padding that may be used in the future. Must be 0.
+ */
__u32 pad;
};
+/**
+ * struct drm_tegra_reloc - GEM object relocation structure
+ */
struct drm_tegra_reloc {
struct {
+ /**
+ * @cmdbuf.handle:
+ *
+ * Handle to the GEM object containing the command buffer for
+ * which to perform this GEM object relocation.
+ */
__u32 handle;
+
+ /**
+ * @cmdbuf.offset:
+ *
+ * Offset, in bytes, into the command buffer at which to
+ * insert the relocated address.
+ */
__u32 offset;
} cmdbuf;
struct {
+ /**
+ * @target.handle:
+ *
+ * Handle to the GEM object to be relocated.
+ */
__u32 handle;
+
+ /**
+ * @target.offset:
+ *
+ * Offset, in bytes, into the target GEM object at which the
+ * relocated data starts.
+ */
__u32 offset;
} target;
+
+ /**
+ * @shift:
+ *
+ * The number of bits by which to shift relocated addresses.
+ */
__u32 shift;
+
+ /**
+ * @pad:
+ *
+ * Structure padding that may be used in the future. Must be 0.
+ */
__u32 pad;
};
+/**
+ * struct drm_tegra_waitchk - wait check structure
+ */
struct drm_tegra_waitchk {
+ /**
+ * @handle:
+ *
+ * Handle to the GEM object containing a command stream on which to
+ * perform the wait check.
+ */
__u32 handle;
+
+ /**
+ * @offset:
+ *
+ * Offset, in bytes, of the location in the command stream to perform
+ * the wait check on.
+ */
__u32 offset;
+
+ /**
+ * @syncpt:
+ *
+ * ID of the syncpoint to wait check.
+ */
__u32 syncpt;
+
+ /**
+ * @thresh:
+ *
+ * Threshold value for which to check.
+ */
__u32 thresh;
};
+/**
+ * struct drm_tegra_submit - job submission structure
+ */
struct drm_tegra_submit {
+ /**
+ * @context:
+ *
+ * The application context identifying the channel to use for the
+ * execution of this job.
+ */
__u64 context;
+
+ /**
+ * @num_syncpts:
+ *
+ * The number of syncpoints operated on by this job. This defines the
+ * length of the array pointed to by @syncpts.
+ */
__u32 num_syncpts;
+
+ /**
+ * @num_cmdbufs:
+ *
+ * The number of command buffers to execute as part of this job. This
+ * defines the length of the array pointed to by @cmdbufs.
+ */
__u32 num_cmdbufs;
+
+ /**
+ * @num_relocs:
+ *
+ * The number of relocations to perform before executing this job.
+ * This defines the length of the array pointed to by @relocs.
+ */
__u32 num_relocs;
+
+ /**
+ * @num_waitchks:
+ *
+ * The number of wait checks to perform as part of this job. This
+ * defines the length of the array pointed to by @waitchks.
+ */
__u32 num_waitchks;
+
+ /**
+ * @waitchk_mask:
+ *
+ * Bitmask of valid wait checks.
+ */
__u32 waitchk_mask;
+
+ /**
+ * @timeout:
+ *
+ * Timeout, in milliseconds, before this job is cancelled.
+ */
__u32 timeout;
- __u32 pad;
+
+ /**
+ * @syncpts:
+ *
+ * A pointer to an array of &struct drm_tegra_syncpt structures that
+ * specify the syncpoint operations performed as part of this job.
+ * The number of elements in the array must be equal to the value
+ * given by @num_syncpts.
+ */
__u64 syncpts;
+
+ /**
+ * @cmdbufs:
+ *
+ * A pointer to an array of &struct drm_tegra_cmdbuf structures that
+ * define the command buffers to execute as part of this job. The
+ * number of elements in the array must be equal to the value given
+ * by @num_syncpts.
+ */
__u64 cmdbufs;
+
+ /**
+ * @relocs:
+ *
+ * A pointer to an array of &struct drm_tegra_reloc structures that
+ * specify the relocations that need to be performed before executing
+ * this job. The number of elements in the array must be equal to the
+ * value given by @num_relocs.
+ */
__u64 relocs;
+
+ /**
+ * @waitchks:
+ *
+ * A pointer to an array of &struct drm_tegra_waitchk structures that
+ * specify the wait checks to be performed while executing this job.
+ * The number of elements in the array must be equal to the value
+ * given by @num_waitchks.
+ */
__u64 waitchks;
- __u32 fence; /* Return value */
- __u32 reserved[5]; /* future expansion */
+ /**
+ * @fence:
+ *
+ * The threshold of the syncpoint associated with this job after it
+ * has been completed. Set by the kernel upon successful completion of
+ * the IOCTL. This can be used with the DRM_TEGRA_SYNCPT_WAIT IOCTL to
+ * wait for this job to be finished.
+ */
+ __u32 fence;
+
+ /**
+ * @reserved:
+ *
+ * This field is reserved for future use. Must be 0.
+ */
+ __u32 reserved[5];
};
#define DRM_TEGRA_GEM_TILING_MODE_PITCH 0
#define DRM_TEGRA_GEM_TILING_MODE_TILED 1
#define DRM_TEGRA_GEM_TILING_MODE_BLOCK 2
+/**
+ * struct drm_tegra_gem_set_tiling - parameters for the set tiling IOCTL
+ */
struct drm_tegra_gem_set_tiling {
- /* input */
+ /**
+ * @handle:
+ *
+ * Handle to the GEM object for which to set the tiling parameters.
+ */
__u32 handle;
+
+ /**
+ * @mode:
+ *
+ * The tiling mode to set. Must be one of:
+ *
+ * DRM_TEGRA_GEM_TILING_MODE_PITCH
+ * pitch linear format
+ *
+ * DRM_TEGRA_GEM_TILING_MODE_TILED
+ * 16x16 tiling format
+ *
+ * DRM_TEGRA_GEM_TILING_MODE_BLOCK
+ * 16Bx2 tiling format
+ */
__u32 mode;
+
+ /**
+ * @value:
+ *
+ * The value to set for the tiling mode parameter.
+ */
__u32 value;
+
+ /**
+ * @pad:
+ *
+ * Structure padding that may be used in the future. Must be 0.
+ */
__u32 pad;
};
+/**
+ * struct drm_tegra_gem_get_tiling - parameters for the get tiling IOCTL
+ */
struct drm_tegra_gem_get_tiling {
- /* input */
+ /**
+ * @handle:
+ *
+ * Handle to the GEM object for which to query the tiling parameters.
+ */
__u32 handle;
- /* output */
+
+ /**
+ * @mode:
+ *
+ * The tiling mode currently associated with the GEM object. Set by
+ * the kernel upon successful completion of the IOCTL.
+ */
__u32 mode;
+
+ /**
+ * @value:
+ *
+ * The tiling mode parameter currently associated with the GEM object.
+ * Set by the kernel upon successful completion of the IOCTL.
+ */
__u32 value;
+
+ /**
+ * @pad:
+ *
+ * Structure padding that may be used in the future. Must be 0.
+ */
__u32 pad;
};
#define DRM_TEGRA_GEM_BOTTOM_UP (1 << 0)
#define DRM_TEGRA_GEM_FLAGS (DRM_TEGRA_GEM_BOTTOM_UP)
+/**
+ * struct drm_tegra_gem_set_flags - parameters for the set flags IOCTL
+ */
struct drm_tegra_gem_set_flags {
- /* input */
+ /**
+ * @handle:
+ *
+ * Handle to the GEM object for which to set the flags.
+ */
__u32 handle;
- /* output */
+
+ /**
+ * @flags:
+ *
+ * The flags to set for the GEM object.
+ */
__u32 flags;
};
+/**
+ * struct drm_tegra_gem_get_flags - parameters for the get flags IOCTL
+ */
struct drm_tegra_gem_get_flags {
- /* input */
+ /**
+ * @handle:
+ *
+ * Handle to the GEM object for which to query the flags.
+ */
__u32 handle;
- /* output */
- __u32 flags;
-};
-enum request_type {
- DRM_TEGRA_REQ_TYPE_CLK_KHZ = 0,
- DRM_TEGRA_REQ_TYPE_BW_KBPS,
-};
-
-struct drm_tegra_get_clk_rate {
- /* class ID*/
- __u32 id;
- /* request type: KBps or KHz */
- __u32 type;
- /* numeric value for type */
- __u64 data;
-};
-
-struct drm_tegra_set_clk_rate {
- /* class ID*/
- __u32 id;
- /* request type: KBps or KHz */
- __u32 type;
- /* numeric value for type */
- __u64 data;
-};
-
-struct drm_tegra_keepon {
- /* channel context (from opening a channel) */
- __u64 context;
+ /**
+ * @flags:
+ *
+ * The flags currently associated with the GEM object. Set by the
+ * kernel upon successful completion of the IOCTL.
+ */
+ __u32 flags;
};
#define DRM_TEGRA_GEM_CREATE 0x00
@@ -205,10 +658,6 @@ struct drm_tegra_keepon {
#define DRM_TEGRA_GEM_GET_TILING 0x0b
#define DRM_TEGRA_GEM_SET_FLAGS 0x0c
#define DRM_TEGRA_GEM_GET_FLAGS 0x0d
-#define DRM_TEGRA_GET_CLK_RATE 0x0e
-#define DRM_TEGRA_SET_CLK_RATE 0x0f
-#define DRM_TEGRA_START_KEEPON 0x10
-#define DRM_TEGRA_STOP_KEEPON 0x11
#define DRM_IOCTL_TEGRA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct drm_tegra_gem_create)
#define DRM_IOCTL_TEGRA_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_MMAP, struct drm_tegra_gem_mmap)
@@ -216,7 +665,7 @@ struct drm_tegra_keepon {
#define DRM_IOCTL_TEGRA_SYNCPT_INCR DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_INCR, struct drm_tegra_syncpt_incr)
#define DRM_IOCTL_TEGRA_SYNCPT_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_WAIT, struct drm_tegra_syncpt_wait)
#define DRM_IOCTL_TEGRA_OPEN_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_OPEN_CHANNEL, struct drm_tegra_open_channel)
-#define DRM_IOCTL_TEGRA_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_CLOSE_CHANNEL, struct drm_tegra_open_channel)
+#define DRM_IOCTL_TEGRA_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_CLOSE_CHANNEL, struct drm_tegra_close_channel)
#define DRM_IOCTL_TEGRA_GET_SYNCPT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT, struct drm_tegra_get_syncpt)
#define DRM_IOCTL_TEGRA_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SUBMIT, struct drm_tegra_submit)
#define DRM_IOCTL_TEGRA_GET_SYNCPT_BASE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT_BASE, struct drm_tegra_get_syncpt_base)
@@ -224,9 +673,9 @@ struct drm_tegra_keepon {
#define DRM_IOCTL_TEGRA_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_TILING, struct drm_tegra_gem_get_tiling)
#define DRM_IOCTL_TEGRA_GEM_SET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_FLAGS, struct drm_tegra_gem_set_flags)
#define DRM_IOCTL_TEGRA_GEM_GET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_FLAGS, struct drm_tegra_gem_get_flags)
-#define DRM_IOCTL_TEGRA_GET_CLK_RATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_CLK_RATE, struct drm_tegra_get_clk_rate)
-#define DRM_IOCTL_TEGRA_SET_CLK_RATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SET_CLK_RATE, struct drm_tegra_set_clk_rate)
-#define DRM_IOCTL_TEGRA_START_KEEPON DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_START_KEEPON, struct drm_tegra_keepon)
-#define DRM_IOCTL_TEGRA_STOP_KEEPON DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_STOP_KEEPON, struct drm_tegra_keepon)
+
+#if defined(__cplusplus)
+}
+#endif
#endif
diff --git a/include/drm/vc4_drm.h b/include/drm/vc4_drm.h
index 319881d8..31f50de3 100644
--- a/include/drm/vc4_drm.h
+++ b/include/drm/vc4_drm.h
@@ -38,6 +38,13 @@ extern "C" {
#define DRM_VC4_CREATE_SHADER_BO 0x05
#define DRM_VC4_GET_HANG_STATE 0x06
#define DRM_VC4_GET_PARAM 0x07
+#define DRM_VC4_SET_TILING 0x08
+#define DRM_VC4_GET_TILING 0x09
+#define DRM_VC4_LABEL_BO 0x0a
+#define DRM_VC4_GEM_MADVISE 0x0b
+#define DRM_VC4_PERFMON_CREATE 0x0c
+#define DRM_VC4_PERFMON_DESTROY 0x0d
+#define DRM_VC4_PERFMON_GET_VALUES 0x0e
#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
@@ -47,6 +54,13 @@ extern "C" {
#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
+#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
+#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
+#define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo)
+#define DRM_IOCTL_VC4_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GEM_MADVISE, struct drm_vc4_gem_madvise)
+#define DRM_IOCTL_VC4_PERFMON_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_CREATE, struct drm_vc4_perfmon_create)
+#define DRM_IOCTL_VC4_PERFMON_DESTROY DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_DESTROY, struct drm_vc4_perfmon_destroy)
+#define DRM_IOCTL_VC4_PERFMON_GET_VALUES DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_PERFMON_GET_VALUES, struct drm_vc4_perfmon_get_values)
struct drm_vc4_submit_rcl_surface {
__u32 hindex; /* Handle index, or ~0 if not present. */
@@ -149,12 +163,38 @@ struct drm_vc4_submit_cl {
__u32 pad:24;
#define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0)
+/* By default, the kernel gets to choose the order that the tiles are
+ * rendered in. If this is set, then the tiles will be rendered in a
+ * raster order, with the right-to-left vs left-to-right and
+ * top-to-bottom vs bottom-to-top dictated by
+ * VC4_SUBMIT_CL_RCL_ORDER_INCREASING_*. This allows overlapping
+ * blits to be implemented using the 3D engine.
+ */
+#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3)
__u32 flags;
/* Returned value of the seqno of this render job (for the
* wait ioctl).
*/
__u64 seqno;
+
+ /* ID of the perfmon to attach to this job. 0 means no perfmon. */
+ __u32 perfmonid;
+
+ /* Syncobj handle to wait on. If set, processing of this render job
+ * will not start until the syncobj is signaled. 0 means ignore.
+ */
+ __u32 in_sync;
+
+ /* Syncobj handle to export fence to. If set, the fence in the syncobj
+ * will be replaced with a fence that signals upon completion of this
+ * render job. 0 means ignore.
+ */
+ __u32 out_sync;
+
+ __u32 pad2;
};
/**
@@ -288,6 +328,9 @@ struct drm_vc4_get_hang_state {
#define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
#define DRM_VC4_PARAM_SUPPORTS_ETC1 4
#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
+#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
+#define DRM_VC4_PARAM_SUPPORTS_MADVISE 7
+#define DRM_VC4_PARAM_SUPPORTS_PERFMON 8
struct drm_vc4_get_param {
__u32 param;
@@ -295,6 +338,103 @@ struct drm_vc4_get_param {
__u64 value;
};
+struct drm_vc4_get_tiling {
+ __u32 handle;
+ __u32 flags;
+ __u64 modifier;
+};
+
+struct drm_vc4_set_tiling {
+ __u32 handle;
+ __u32 flags;
+ __u64 modifier;
+};
+
+/**
+ * struct drm_vc4_label_bo - Attach a name to a BO for debug purposes.
+ */
+struct drm_vc4_label_bo {
+ __u32 handle;
+ __u32 len;
+ __u64 name;
+};
+
+/*
+ * States prefixed with '__' are internal states and cannot be passed to the
+ * DRM_IOCTL_VC4_GEM_MADVISE ioctl.
+ */
+#define VC4_MADV_WILLNEED 0
+#define VC4_MADV_DONTNEED 1
+#define __VC4_MADV_PURGED 2
+#define __VC4_MADV_NOTSUPP 3
+
+struct drm_vc4_gem_madvise {
+ __u32 handle;
+ __u32 madv;
+ __u32 retained;
+ __u32 pad;
+};
+
+enum {
+ VC4_PERFCNT_FEP_VALID_PRIMS_NO_RENDER,
+ VC4_PERFCNT_FEP_VALID_PRIMS_RENDER,
+ VC4_PERFCNT_FEP_CLIPPED_QUADS,
+ VC4_PERFCNT_FEP_VALID_QUADS,
+ VC4_PERFCNT_TLB_QUADS_NOT_PASSING_STENCIL,
+ VC4_PERFCNT_TLB_QUADS_NOT_PASSING_Z_AND_STENCIL,
+ VC4_PERFCNT_TLB_QUADS_PASSING_Z_AND_STENCIL,
+ VC4_PERFCNT_TLB_QUADS_ZERO_COVERAGE,
+ VC4_PERFCNT_TLB_QUADS_NON_ZERO_COVERAGE,
+ VC4_PERFCNT_TLB_QUADS_WRITTEN_TO_COLOR_BUF,
+ VC4_PERFCNT_PLB_PRIMS_OUTSIDE_VIEWPORT,
+ VC4_PERFCNT_PLB_PRIMS_NEED_CLIPPING,
+ VC4_PERFCNT_PSE_PRIMS_REVERSED,
+ VC4_PERFCNT_QPU_TOTAL_IDLE_CYCLES,
+ VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_VERTEX_COORD_SHADING,
+ VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_FRAGMENT_SHADING,
+ VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_EXEC_VALID_INST,
+ VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_TMUS,
+ VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_SCOREBOARD,
+ VC4_PERFCNT_QPU_TOTAL_CLK_CYCLES_WAITING_VARYINGS,
+ VC4_PERFCNT_QPU_TOTAL_INST_CACHE_HIT,
+ VC4_PERFCNT_QPU_TOTAL_INST_CACHE_MISS,
+ VC4_PERFCNT_QPU_TOTAL_UNIFORM_CACHE_HIT,
+ VC4_PERFCNT_QPU_TOTAL_UNIFORM_CACHE_MISS,
+ VC4_PERFCNT_TMU_TOTAL_TEXT_QUADS_PROCESSED,
+ VC4_PERFCNT_TMU_TOTAL_TEXT_CACHE_MISS,
+ VC4_PERFCNT_VPM_TOTAL_CLK_CYCLES_VDW_STALLED,
+ VC4_PERFCNT_VPM_TOTAL_CLK_CYCLES_VCD_STALLED,
+ VC4_PERFCNT_L2C_TOTAL_L2_CACHE_HIT,
+ VC4_PERFCNT_L2C_TOTAL_L2_CACHE_MISS,
+ VC4_PERFCNT_NUM_EVENTS,
+};
+
+#define DRM_VC4_MAX_PERF_COUNTERS 16
+
+struct drm_vc4_perfmon_create {
+ __u32 id;
+ __u32 ncounters;
+ __u8 events[DRM_VC4_MAX_PERF_COUNTERS];
+};
+
+struct drm_vc4_perfmon_destroy {
+ __u32 id;
+};
+
+/*
+ * Returns the values of the performance counters tracked by this
+ * perfmon (as an array of ncounters u64 values).
+ *
+ * No implicit synchronization is performed, so the user has to
+ * guarantee that any jobs using this perfmon have already been
+ * completed (probably by blocking on the seqno returned by the
+ * last exec that used the perfmon).
+ */
+struct drm_vc4_perfmon_get_values {
+ __u32 id;
+ __u64 values_ptr;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/drm/via_drm.h b/include/drm/via_drm.h
index 182f8792..8b69e819 100644
--- a/include/drm/via_drm.h
+++ b/include/drm/via_drm.h
@@ -26,6 +26,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/* WARNING: These defines must be the same as what the Xserver uses.
* if you change them, you must change the defines in the Xserver.
*/
@@ -272,4 +276,8 @@ typedef struct drm_via_dmablit {
drm_via_blitsync_t sync;
} drm_via_dmablit_t;
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* _VIA_DRM_H_ */
diff --git a/include/drm/virtgpu_drm.h b/include/drm/virtgpu_drm.h
index 91a31ffe..9a781f06 100644
--- a/include/drm/virtgpu_drm.h
+++ b/include/drm/virtgpu_drm.h
@@ -63,6 +63,7 @@ struct drm_virtgpu_execbuffer {
};
#define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */
+#define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */
struct drm_virtgpu_getparam {
__u64 param;
diff --git a/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h
index 5b68b4d1..0bc784f5 100644
--- a/include/drm/vmwgfx_drm.h
+++ b/include/drm/vmwgfx_drm.h
@@ -30,6 +30,10 @@
#include "drm.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
#define DRM_VMW_MAX_SURFACE_FACES 6
#define DRM_VMW_MAX_MIP_LEVELS 24
@@ -37,6 +41,7 @@
#define DRM_VMW_GET_PARAM 0
#define DRM_VMW_ALLOC_DMABUF 1
#define DRM_VMW_UNREF_DMABUF 2
+#define DRM_VMW_HANDLE_CLOSE 2
#define DRM_VMW_CURSOR_BYPASS 3
/* guarded by DRM_VMW_PARAM_NUM_STREAMS != 0*/
#define DRM_VMW_CONTROL_STREAM 4
@@ -292,13 +297,17 @@ union drm_vmw_surface_reference_arg {
* @version: Allows expanding the execbuf ioctl parameters without breaking
* backwards compatibility, since user-space will always tell the kernel
* which version it uses.
- * @flags: Execbuf flags. None currently.
+ * @flags: Execbuf flags.
+ * @imported_fence_fd: FD for a fence imported from another device
*
* Argument to the DRM_VMW_EXECBUF Ioctl.
*/
#define DRM_VMW_EXECBUF_VERSION 2
+#define DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD (1 << 0)
+#define DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD (1 << 1)
+
struct drm_vmw_execbuf_arg {
__u64 commands;
__u32 command_size;
@@ -307,7 +316,7 @@ struct drm_vmw_execbuf_arg {
__u32 version;
__u32 flags;
__u32 context_handle;
- __u32 pad64;
+ __s32 imported_fence_fd;
};
/**
@@ -323,6 +332,7 @@ struct drm_vmw_execbuf_arg {
* @passed_seqno: The highest seqno number processed by the hardware
* so far. This can be used to mark user-space fence objects as signaled, and
* to determine whether a fence seqno might be stale.
+ * @fd: FD associated with the fence, -1 if not exported
* @error: This member should've been set to -EFAULT on submission.
* The following actions should be take on completion:
* error == -EFAULT: Fence communication failed. The host is synchronized.
@@ -340,7 +350,7 @@ struct drm_vmw_fence_rep {
__u32 mask;
__u32 seqno;
__u32 passed_seqno;
- __u32 pad64;
+ __s32 fd;
__s32 error;
};
@@ -1087,4 +1097,32 @@ union drm_vmw_extended_context_arg {
enum drm_vmw_extended_context req;
struct drm_vmw_context_arg rep;
};
+
+/*************************************************************************/
+/*
+ * DRM_VMW_HANDLE_CLOSE - Close a user-space handle and release its
+ * underlying resource.
+ *
+ * Note that this ioctl is overlaid on the DRM_VMW_UNREF_DMABUF Ioctl.
+ * The ioctl arguments therefore need to be identical in layout.
+ *
+ */
+
+/**
+ * struct drm_vmw_handle_close_arg
+ *
+ * @handle: Handle to close.
+ *
+ * Argument to the DRM_VMW_HANDLE_CLOSE Ioctl.
+ */
+struct drm_vmw_handle_close_arg {
+ __u32 handle;
+ __u32 pad64;
+};
+
+
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/intel/Android.sources.bp b/intel/Android.sources.bp
index 459c070f..46e0328f 100644
--- a/intel/Android.sources.bp
+++ b/intel/Android.sources.bp
@@ -7,6 +7,7 @@ cc_defaults {
"intel_bufmgr_fake.c",
"intel_bufmgr_gem.c",
"intel_decode.c",
+ "intel_chipset.c",
"mm.c",
],
}
diff --git a/intel/Makefile.am b/intel/Makefile.am
index c52e8c08..bad44f5f 100644
--- a/intel/Makefile.am
+++ b/intel/Makefile.am
@@ -26,6 +26,7 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
$(PCIACCESS_CFLAGS) \
@@ -56,6 +57,7 @@ BATCHES = \
tests/gen7-2d-copy.batch \
tests/gen7-3d.batch
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = \
$(BATCHES:.batch=.batch.sh) \
intel-symbol-check
diff --git a/intel/Makefile.sources b/intel/Makefile.sources
index 6947ab74..aa27e273 100644
--- a/intel/Makefile.sources
+++ b/intel/Makefile.sources
@@ -1,10 +1,12 @@
LIBDRM_INTEL_FILES := \
+ i915_pciids.h \
intel_bufmgr.c \
intel_bufmgr_priv.h \
intel_bufmgr_fake.c \
intel_bufmgr_gem.c \
intel_decode.c \
intel_chipset.h \
+ intel_chipset.c \
mm.c \
mm.h \
uthash.h
diff --git a/intel/i915_pciids.h b/intel/i915_pciids.h
new file mode 100644
index 00000000..fd965ffb
--- /dev/null
+++ b/intel/i915_pciids.h
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2013 Intel Corporation
+ * 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 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 _I915_PCIIDS_H
+#define _I915_PCIIDS_H
+
+/*
+ * A pci_device_id struct {
+ * __u32 vendor, device;
+ * __u32 subvendor, subdevice;
+ * __u32 class, class_mask;
+ * kernel_ulong_t driver_data;
+ * };
+ * Don't use C99 here because "class" is reserved and we want to
+ * give userspace flexibility.
+ */
+#define INTEL_VGA_DEVICE(id, info) { \
+ 0x8086, id, \
+ ~0, ~0, \
+ 0x030000, 0xff0000, \
+ (unsigned long) info }
+
+#define INTEL_QUANTA_VGA_DEVICE(info) { \
+ 0x8086, 0x16a, \
+ 0x152d, 0x8990, \
+ 0x030000, 0xff0000, \
+ (unsigned long) info }
+
+#define INTEL_I810_IDS(info) \
+ INTEL_VGA_DEVICE(0x7121, info), /* I810 */ \
+ INTEL_VGA_DEVICE(0x7123, info), /* I810_DC100 */ \
+ INTEL_VGA_DEVICE(0x7125, info) /* I810_E */
+
+#define INTEL_I815_IDS(info) \
+ INTEL_VGA_DEVICE(0x1132, info) /* I815*/
+
+#define INTEL_I830_IDS(info) \
+ INTEL_VGA_DEVICE(0x3577, info)
+
+#define INTEL_I845G_IDS(info) \
+ INTEL_VGA_DEVICE(0x2562, info)
+
+#define INTEL_I85X_IDS(info) \
+ INTEL_VGA_DEVICE(0x3582, info), /* I855_GM */ \
+ INTEL_VGA_DEVICE(0x358e, info)
+
+#define INTEL_I865G_IDS(info) \
+ INTEL_VGA_DEVICE(0x2572, info) /* I865_G */
+
+#define INTEL_I915G_IDS(info) \
+ INTEL_VGA_DEVICE(0x2582, info), /* I915_G */ \
+ INTEL_VGA_DEVICE(0x258a, info) /* E7221_G */
+
+#define INTEL_I915GM_IDS(info) \
+ INTEL_VGA_DEVICE(0x2592, info) /* I915_GM */
+
+#define INTEL_I945G_IDS(info) \
+ INTEL_VGA_DEVICE(0x2772, info) /* I945_G */
+
+#define INTEL_I945GM_IDS(info) \
+ INTEL_VGA_DEVICE(0x27a2, info), /* I945_GM */ \
+ INTEL_VGA_DEVICE(0x27ae, info) /* I945_GME */
+
+#define INTEL_I965G_IDS(info) \
+ INTEL_VGA_DEVICE(0x2972, info), /* I946_GZ */ \
+ INTEL_VGA_DEVICE(0x2982, info), /* G35_G */ \
+ INTEL_VGA_DEVICE(0x2992, info), /* I965_Q */ \
+ INTEL_VGA_DEVICE(0x29a2, info) /* I965_G */
+
+#define INTEL_G33_IDS(info) \
+ INTEL_VGA_DEVICE(0x29b2, info), /* Q35_G */ \
+ INTEL_VGA_DEVICE(0x29c2, info), /* G33_G */ \
+ INTEL_VGA_DEVICE(0x29d2, info) /* Q33_G */
+
+#define INTEL_I965GM_IDS(info) \
+ INTEL_VGA_DEVICE(0x2a02, info), /* I965_GM */ \
+ INTEL_VGA_DEVICE(0x2a12, info) /* I965_GME */
+
+#define INTEL_GM45_IDS(info) \
+ INTEL_VGA_DEVICE(0x2a42, info) /* GM45_G */
+
+#define INTEL_G45_IDS(info) \
+ INTEL_VGA_DEVICE(0x2e02, info), /* IGD_E_G */ \
+ INTEL_VGA_DEVICE(0x2e12, info), /* Q45_G */ \
+ INTEL_VGA_DEVICE(0x2e22, info), /* G45_G */ \
+ INTEL_VGA_DEVICE(0x2e32, info), /* G41_G */ \
+ INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \
+ INTEL_VGA_DEVICE(0x2e92, info) /* B43_G.1 */
+
+#define INTEL_PINEVIEW_IDS(info) \
+ INTEL_VGA_DEVICE(0xa001, info), \
+ INTEL_VGA_DEVICE(0xa011, info)
+
+#define INTEL_IRONLAKE_D_IDS(info) \
+ INTEL_VGA_DEVICE(0x0042, info)
+
+#define INTEL_IRONLAKE_M_IDS(info) \
+ INTEL_VGA_DEVICE(0x0046, info)
+
+#define INTEL_SNB_D_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x0102, info), \
+ INTEL_VGA_DEVICE(0x010A, info)
+
+#define INTEL_SNB_D_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x0112, info), \
+ INTEL_VGA_DEVICE(0x0122, info)
+
+#define INTEL_SNB_D_IDS(info) \
+ INTEL_SNB_D_GT1_IDS(info), \
+ INTEL_SNB_D_GT2_IDS(info)
+
+#define INTEL_SNB_M_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x0106, info)
+
+#define INTEL_SNB_M_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x0116, info), \
+ INTEL_VGA_DEVICE(0x0126, info)
+
+#define INTEL_SNB_M_IDS(info) \
+ INTEL_SNB_M_GT1_IDS(info), \
+ INTEL_SNB_M_GT2_IDS(info)
+
+#define INTEL_IVB_M_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x0156, info) /* GT1 mobile */
+
+#define INTEL_IVB_M_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x0166, info) /* GT2 mobile */
+
+#define INTEL_IVB_M_IDS(info) \
+ INTEL_IVB_M_GT1_IDS(info), \
+ INTEL_IVB_M_GT2_IDS(info)
+
+#define INTEL_IVB_D_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x0152, info), /* GT1 desktop */ \
+ INTEL_VGA_DEVICE(0x015a, info) /* GT1 server */
+
+#define INTEL_IVB_D_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x0162, info), /* GT2 desktop */ \
+ INTEL_VGA_DEVICE(0x016a, info) /* GT2 server */
+
+#define INTEL_IVB_D_IDS(info) \
+ INTEL_IVB_D_GT1_IDS(info), \
+ INTEL_IVB_D_GT2_IDS(info)
+
+#define INTEL_IVB_Q_IDS(info) \
+ INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */
+
+#define INTEL_HSW_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x0402, info), /* GT1 desktop */ \
+ INTEL_VGA_DEVICE(0x040a, info), /* GT1 server */ \
+ INTEL_VGA_DEVICE(0x040B, info), /* GT1 reserved */ \
+ INTEL_VGA_DEVICE(0x040E, info), /* GT1 reserved */ \
+ INTEL_VGA_DEVICE(0x0C02, info), /* SDV GT1 desktop */ \
+ INTEL_VGA_DEVICE(0x0C0A, info), /* SDV GT1 server */ \
+ INTEL_VGA_DEVICE(0x0C0B, info), /* SDV GT1 reserved */ \
+ INTEL_VGA_DEVICE(0x0C0E, info), /* SDV GT1 reserved */ \
+ INTEL_VGA_DEVICE(0x0A02, info), /* ULT GT1 desktop */ \
+ INTEL_VGA_DEVICE(0x0A0A, info), /* ULT GT1 server */ \
+ INTEL_VGA_DEVICE(0x0A0B, info), /* ULT GT1 reserved */ \
+ INTEL_VGA_DEVICE(0x0D02, info), /* CRW GT1 desktop */ \
+ INTEL_VGA_DEVICE(0x0D0A, info), /* CRW GT1 server */ \
+ INTEL_VGA_DEVICE(0x0D0B, info), /* CRW GT1 reserved */ \
+ INTEL_VGA_DEVICE(0x0D0E, info), /* CRW GT1 reserved */ \
+ INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \
+ INTEL_VGA_DEVICE(0x0C06, info), /* SDV GT1 mobile */ \
+ INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \
+ INTEL_VGA_DEVICE(0x0A0E, info), /* ULX GT1 mobile */ \
+ INTEL_VGA_DEVICE(0x0D06, info) /* CRW GT1 mobile */
+
+#define INTEL_HSW_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x0412, info), /* GT2 desktop */ \
+ INTEL_VGA_DEVICE(0x041a, info), /* GT2 server */ \
+ INTEL_VGA_DEVICE(0x041B, info), /* GT2 reserved */ \
+ INTEL_VGA_DEVICE(0x041E, info), /* GT2 reserved */ \
+ INTEL_VGA_DEVICE(0x0C12, info), /* SDV GT2 desktop */ \
+ INTEL_VGA_DEVICE(0x0C1A, info), /* SDV GT2 server */ \
+ INTEL_VGA_DEVICE(0x0C1B, info), /* SDV GT2 reserved */ \
+ INTEL_VGA_DEVICE(0x0C1E, info), /* SDV GT2 reserved */ \
+ INTEL_VGA_DEVICE(0x0A12, info), /* ULT GT2 desktop */ \
+ INTEL_VGA_DEVICE(0x0A1A, info), /* ULT GT2 server */ \
+ INTEL_VGA_DEVICE(0x0A1B, info), /* ULT GT2 reserved */ \
+ INTEL_VGA_DEVICE(0x0D12, info), /* CRW GT2 desktop */ \
+ INTEL_VGA_DEVICE(0x0D1A, info), /* CRW GT2 server */ \
+ INTEL_VGA_DEVICE(0x0D1B, info), /* CRW GT2 reserved */ \
+ INTEL_VGA_DEVICE(0x0D1E, info), /* CRW GT2 reserved */ \
+ INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \
+ INTEL_VGA_DEVICE(0x0426, info), /* GT2 mobile */ \
+ INTEL_VGA_DEVICE(0x0C16, info), /* SDV GT2 mobile */ \
+ INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \
+ INTEL_VGA_DEVICE(0x0A1E, info), /* ULX GT2 mobile */ \
+ INTEL_VGA_DEVICE(0x0D16, info) /* CRW GT2 mobile */
+
+#define INTEL_HSW_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x0422, info), /* GT3 desktop */ \
+ INTEL_VGA_DEVICE(0x042a, info), /* GT3 server */ \
+ INTEL_VGA_DEVICE(0x042B, info), /* GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x042E, info), /* GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x0C22, info), /* SDV GT3 desktop */ \
+ INTEL_VGA_DEVICE(0x0C2A, info), /* SDV GT3 server */ \
+ INTEL_VGA_DEVICE(0x0C2B, info), /* SDV GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x0C2E, info), /* SDV GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x0A22, info), /* ULT GT3 desktop */ \
+ INTEL_VGA_DEVICE(0x0A2A, info), /* ULT GT3 server */ \
+ INTEL_VGA_DEVICE(0x0A2B, info), /* ULT GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x0D22, info), /* CRW GT3 desktop */ \
+ INTEL_VGA_DEVICE(0x0D2A, info), /* CRW GT3 server */ \
+ INTEL_VGA_DEVICE(0x0D2B, info), /* CRW GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x0D2E, info), /* CRW GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x0C26, info), /* SDV GT3 mobile */ \
+ INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \
+ INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x0D26, info) /* CRW GT3 mobile */
+
+#define INTEL_HSW_IDS(info) \
+ INTEL_HSW_GT1_IDS(info), \
+ INTEL_HSW_GT2_IDS(info), \
+ INTEL_HSW_GT3_IDS(info)
+
+#define INTEL_VLV_IDS(info) \
+ INTEL_VGA_DEVICE(0x0f30, info), \
+ INTEL_VGA_DEVICE(0x0f31, info), \
+ INTEL_VGA_DEVICE(0x0f32, info), \
+ INTEL_VGA_DEVICE(0x0f33, info), \
+ INTEL_VGA_DEVICE(0x0157, info), \
+ INTEL_VGA_DEVICE(0x0155, info)
+
+#define INTEL_BDW_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \
+ INTEL_VGA_DEVICE(0x1606, info), /* GT1 ULT */ \
+ INTEL_VGA_DEVICE(0x160B, info), /* GT1 Iris */ \
+ INTEL_VGA_DEVICE(0x160E, info), /* GT1 ULX */ \
+ INTEL_VGA_DEVICE(0x160A, info), /* GT1 Server */ \
+ INTEL_VGA_DEVICE(0x160D, info) /* GT1 Workstation */
+
+#define INTEL_BDW_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */ \
+ INTEL_VGA_DEVICE(0x1616, info), /* GT2 ULT */ \
+ INTEL_VGA_DEVICE(0x161B, info), /* GT2 ULT */ \
+ INTEL_VGA_DEVICE(0x161E, info), /* GT2 ULX */ \
+ INTEL_VGA_DEVICE(0x161A, info), /* GT2 Server */ \
+ INTEL_VGA_DEVICE(0x161D, info) /* GT2 Workstation */
+
+#define INTEL_BDW_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x1622, info), /* ULT */ \
+ INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \
+ INTEL_VGA_DEVICE(0x162B, info), /* Iris */ \
+ INTEL_VGA_DEVICE(0x162E, info), /* ULX */\
+ INTEL_VGA_DEVICE(0x162A, info), /* Server */ \
+ INTEL_VGA_DEVICE(0x162D, info) /* Workstation */
+
+#define INTEL_BDW_RSVD_IDS(info) \
+ INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \
+ INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \
+ INTEL_VGA_DEVICE(0x163B, info), /* Iris */ \
+ INTEL_VGA_DEVICE(0x163E, info), /* ULX */ \
+ INTEL_VGA_DEVICE(0x163A, info), /* Server */ \
+ INTEL_VGA_DEVICE(0x163D, info) /* Workstation */
+
+#define INTEL_BDW_IDS(info) \
+ INTEL_BDW_GT1_IDS(info), \
+ INTEL_BDW_GT2_IDS(info), \
+ INTEL_BDW_GT3_IDS(info), \
+ INTEL_BDW_RSVD_IDS(info)
+
+#define INTEL_CHV_IDS(info) \
+ INTEL_VGA_DEVICE(0x22b0, info), \
+ INTEL_VGA_DEVICE(0x22b1, info), \
+ INTEL_VGA_DEVICE(0x22b2, info), \
+ INTEL_VGA_DEVICE(0x22b3, info)
+
+#define INTEL_SKL_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \
+ INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \
+ INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \
+ INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \
+ INTEL_VGA_DEVICE(0x190A, info) /* SRV GT1 */
+
+#define INTEL_SKL_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \
+ INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \
+ INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */ \
+ INTEL_VGA_DEVICE(0x1912, info), /* DT GT2 */ \
+ INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \
+ INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \
+ INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */
+
+#define INTEL_SKL_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \
+ INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \
+ INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */ \
+ INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \
+ INTEL_VGA_DEVICE(0x192D, info) /* SRV GT3 */
+
+#define INTEL_SKL_GT4_IDS(info) \
+ INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \
+ INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */ \
+ INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \
+ INTEL_VGA_DEVICE(0x192A, info), /* SRV GT4 */ \
+ INTEL_VGA_DEVICE(0x193A, info) /* SRV GT4e */
+
+#define INTEL_SKL_IDS(info) \
+ INTEL_SKL_GT1_IDS(info), \
+ INTEL_SKL_GT2_IDS(info), \
+ INTEL_SKL_GT3_IDS(info), \
+ INTEL_SKL_GT4_IDS(info)
+
+#define INTEL_BXT_IDS(info) \
+ INTEL_VGA_DEVICE(0x0A84, info), \
+ INTEL_VGA_DEVICE(0x1A84, info), \
+ INTEL_VGA_DEVICE(0x1A85, info), \
+ INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \
+ INTEL_VGA_DEVICE(0x5A85, info) /* APL HD Graphics 500 */
+
+#define INTEL_GLK_IDS(info) \
+ INTEL_VGA_DEVICE(0x3184, info), \
+ INTEL_VGA_DEVICE(0x3185, info)
+
+#define INTEL_KBL_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \
+ INTEL_VGA_DEVICE(0x5915, info), /* ULX GT1.5 */ \
+ INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \
+ INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \
+ INTEL_VGA_DEVICE(0x5902, info), /* DT GT1 */ \
+ INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */ \
+ INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */ \
+ INTEL_VGA_DEVICE(0x590A, info) /* SRV GT1 */
+
+#define INTEL_KBL_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */ \
+ INTEL_VGA_DEVICE(0x5917, info), /* Mobile GT2 */ \
+ INTEL_VGA_DEVICE(0x5921, info), /* ULT GT2F */ \
+ INTEL_VGA_DEVICE(0x591E, info), /* ULX GT2 */ \
+ INTEL_VGA_DEVICE(0x5912, info), /* DT GT2 */ \
+ INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \
+ INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */ \
+ INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */
+
+#define INTEL_KBL_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */ \
+ INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */ \
+ INTEL_VGA_DEVICE(0x5927, info) /* ULT GT3 */
+
+#define INTEL_KBL_GT4_IDS(info) \
+ INTEL_VGA_DEVICE(0x593B, info) /* Halo GT4 */
+
+/* AML/KBL Y GT2 */
+#define INTEL_AML_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x591C, info), /* ULX GT2 */ \
+ INTEL_VGA_DEVICE(0x87C0, info) /* ULX GT2 */
+
+#define INTEL_KBL_IDS(info) \
+ INTEL_KBL_GT1_IDS(info), \
+ INTEL_KBL_GT2_IDS(info), \
+ INTEL_KBL_GT3_IDS(info), \
+ INTEL_KBL_GT4_IDS(info), \
+ INTEL_AML_GT2_IDS(info)
+
+/* CFL S */
+#define INTEL_CFL_S_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x3E90, info), /* SRV GT1 */ \
+ INTEL_VGA_DEVICE(0x3E93, info), /* SRV GT1 */ \
+ INTEL_VGA_DEVICE(0x3E99, info) /* SRV GT1 */
+
+#define INTEL_CFL_S_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x3E91, info), /* SRV GT2 */ \
+ INTEL_VGA_DEVICE(0x3E92, info), /* SRV GT2 */ \
+ INTEL_VGA_DEVICE(0x3E96, info), /* SRV GT2 */ \
+ INTEL_VGA_DEVICE(0x3E98, info), /* SRV GT2 */ \
+ INTEL_VGA_DEVICE(0x3E9A, info) /* SRV GT2 */
+
+/* CFL H */
+#define INTEL_CFL_H_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x3E9B, info), /* Halo GT2 */ \
+ INTEL_VGA_DEVICE(0x3E94, info) /* Halo GT2 */
+
+/* CFL U GT2 */
+#define INTEL_CFL_U_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x3EA9, info)
+
+/* CFL U GT3 */
+#define INTEL_CFL_U_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x3EA5, info), /* ULT GT3 */ \
+ INTEL_VGA_DEVICE(0x3EA6, info), /* ULT GT3 */ \
+ INTEL_VGA_DEVICE(0x3EA7, info), /* ULT GT3 */ \
+ INTEL_VGA_DEVICE(0x3EA8, info) /* ULT GT3 */
+
+/* WHL/CFL U GT1 */
+#define INTEL_WHL_U_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x3EA1, info)
+
+/* WHL/CFL U GT2 */
+#define INTEL_WHL_U_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x3EA0, info)
+
+/* WHL/CFL U GT3 */
+#define INTEL_WHL_U_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x3EA2, info), \
+ INTEL_VGA_DEVICE(0x3EA3, info), \
+ INTEL_VGA_DEVICE(0x3EA4, info)
+
+#define INTEL_CFL_IDS(info) \
+ INTEL_CFL_S_GT1_IDS(info), \
+ INTEL_CFL_S_GT2_IDS(info), \
+ INTEL_CFL_H_GT2_IDS(info), \
+ INTEL_CFL_U_GT2_IDS(info), \
+ INTEL_CFL_U_GT3_IDS(info), \
+ INTEL_WHL_U_GT1_IDS(info), \
+ INTEL_WHL_U_GT2_IDS(info), \
+ INTEL_WHL_U_GT3_IDS(info)
+
+/* CNL */
+#define INTEL_CNL_IDS(info) \
+ INTEL_VGA_DEVICE(0x5A51, info), \
+ INTEL_VGA_DEVICE(0x5A59, info), \
+ INTEL_VGA_DEVICE(0x5A41, info), \
+ INTEL_VGA_DEVICE(0x5A49, info), \
+ INTEL_VGA_DEVICE(0x5A52, info), \
+ INTEL_VGA_DEVICE(0x5A5A, info), \
+ INTEL_VGA_DEVICE(0x5A42, info), \
+ INTEL_VGA_DEVICE(0x5A4A, info), \
+ INTEL_VGA_DEVICE(0x5A50, info), \
+ INTEL_VGA_DEVICE(0x5A40, info), \
+ INTEL_VGA_DEVICE(0x5A54, info), \
+ INTEL_VGA_DEVICE(0x5A5C, info), \
+ INTEL_VGA_DEVICE(0x5A44, info), \
+ INTEL_VGA_DEVICE(0x5A4C, info)
+
+/* ICL */
+#define INTEL_ICL_11_IDS(info) \
+ INTEL_VGA_DEVICE(0x8A50, info), \
+ INTEL_VGA_DEVICE(0x8A51, info), \
+ INTEL_VGA_DEVICE(0x8A5C, info), \
+ INTEL_VGA_DEVICE(0x8A5D, info), \
+ INTEL_VGA_DEVICE(0x8A52, info), \
+ INTEL_VGA_DEVICE(0x8A5A, info), \
+ INTEL_VGA_DEVICE(0x8A5B, info), \
+ INTEL_VGA_DEVICE(0x8A71, info), \
+ INTEL_VGA_DEVICE(0x8A70, info)
+
+#endif /* _I915_PCIIDS_H */
diff --git a/intel/intel-symbol-check b/intel/intel-symbol-check
index 2aa2d819..de377bef 100755
--- a/intel/intel-symbol-check
+++ b/intel/intel-symbol-check
@@ -1,9 +1,11 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.sources/LIBDRM_INTEL_H_FILES
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_intel.so} | awk '{print $3}' | while read func; do
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_intel.so} | awk '{print $3}' | while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
__bss_start
_edata
diff --git a/intel/intel_bufmgr.c b/intel/intel_bufmgr.c
index 5bad93fa..68d97c0e 100644
--- a/intel/intel_bufmgr.c
+++ b/intel/intel_bufmgr.c
@@ -25,10 +25,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
@@ -49,21 +45,21 @@
* Convenience functions for buffer management methods.
*/
-drm_intel_bo *
+drm_public drm_intel_bo *
drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
unsigned long size, unsigned int alignment)
{
return bufmgr->bo_alloc(bufmgr, name, size, alignment);
}
-drm_intel_bo *
+drm_public drm_intel_bo *
drm_intel_bo_alloc_for_render(drm_intel_bufmgr *bufmgr, const char *name,
unsigned long size, unsigned int alignment)
{
return bufmgr->bo_alloc_for_render(bufmgr, name, size, alignment);
}
-drm_intel_bo *
+drm_public drm_intel_bo *
drm_intel_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
const char *name, void *addr,
uint32_t tiling_mode,
@@ -77,7 +73,7 @@ drm_intel_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
return NULL;
}
-drm_intel_bo *
+drm_public drm_intel_bo *
drm_intel_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
int x, int y, int cpp, uint32_t *tiling_mode,
unsigned long *pitch, unsigned long flags)
@@ -86,13 +82,13 @@ drm_intel_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
tiling_mode, pitch, flags);
}
-void
+drm_public void
drm_intel_bo_reference(drm_intel_bo *bo)
{
bo->bufmgr->bo_reference(bo);
}
-void
+drm_public void
drm_intel_bo_unreference(drm_intel_bo *bo)
{
if (bo == NULL)
@@ -101,26 +97,26 @@ drm_intel_bo_unreference(drm_intel_bo *bo)
bo->bufmgr->bo_unreference(bo);
}
-int
+drm_public int
drm_intel_bo_map(drm_intel_bo *buf, int write_enable)
{
return buf->bufmgr->bo_map(buf, write_enable);
}
-int
+drm_public int
drm_intel_bo_unmap(drm_intel_bo *buf)
{
return buf->bufmgr->bo_unmap(buf);
}
-int
+drm_public int
drm_intel_bo_subdata(drm_intel_bo *bo, unsigned long offset,
unsigned long size, const void *data)
{
return bo->bufmgr->bo_subdata(bo, offset, size, data);
}
-int
+drm_public int
drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
unsigned long size, void *data)
{
@@ -139,26 +135,26 @@ drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
return 0;
}
-void
+drm_public void
drm_intel_bo_wait_rendering(drm_intel_bo *bo)
{
bo->bufmgr->bo_wait_rendering(bo);
}
-void
+drm_public void
drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr)
{
bufmgr->destroy(bufmgr);
}
-int
+drm_public int
drm_intel_bo_exec(drm_intel_bo *bo, int used,
drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
{
return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4);
}
-int
+drm_public int
drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
unsigned int rings)
@@ -178,19 +174,19 @@ drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
}
}
-void
+drm_public void
drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug)
{
bufmgr->debug = enable_debug;
}
-int
+drm_public int
drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
{
return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
}
-int
+drm_public int
drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
{
if (bo->bufmgr->bo_flink)
@@ -199,7 +195,7 @@ drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
return -ENODEV;
}
-int
+drm_public int
drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
drm_intel_bo *target_bo, uint32_t target_offset,
uint32_t read_domains, uint32_t write_domain)
@@ -210,7 +206,7 @@ drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
}
/* For fence registers, not GL fences */
-int
+drm_public int
drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
drm_intel_bo *target_bo, uint32_t target_offset,
uint32_t read_domains, uint32_t write_domain)
@@ -221,7 +217,7 @@ drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
}
-int
+drm_public int
drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
{
if (bo->bufmgr->bo_pin)
@@ -230,7 +226,7 @@ drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
return -ENODEV;
}
-int
+drm_public int
drm_intel_bo_unpin(drm_intel_bo *bo)
{
if (bo->bufmgr->bo_unpin)
@@ -239,7 +235,7 @@ drm_intel_bo_unpin(drm_intel_bo *bo)
return -ENODEV;
}
-int
+drm_public int
drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
uint32_t stride)
{
@@ -250,7 +246,7 @@ drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
return 0;
}
-int
+drm_public int
drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
uint32_t * swizzle_mode)
{
@@ -262,7 +258,7 @@ drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
return 0;
}
-int
+drm_public int
drm_intel_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset)
{
if (bo->bufmgr->bo_set_softpin_offset)
@@ -271,7 +267,7 @@ drm_intel_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset)
return -ENODEV;
}
-int
+drm_public int
drm_intel_bo_disable_reuse(drm_intel_bo *bo)
{
if (bo->bufmgr->bo_disable_reuse)
@@ -279,7 +275,7 @@ drm_intel_bo_disable_reuse(drm_intel_bo *bo)
return 0;
}
-int
+drm_public int
drm_intel_bo_is_reusable(drm_intel_bo *bo)
{
if (bo->bufmgr->bo_is_reusable)
@@ -287,7 +283,7 @@ drm_intel_bo_is_reusable(drm_intel_bo *bo)
return 0;
}
-int
+drm_public int
drm_intel_bo_busy(drm_intel_bo *bo)
{
if (bo->bufmgr->bo_busy)
@@ -295,7 +291,7 @@ drm_intel_bo_busy(drm_intel_bo *bo)
return 0;
}
-int
+drm_public int
drm_intel_bo_madvise(drm_intel_bo *bo, int madv)
{
if (bo->bufmgr->bo_madvise)
@@ -303,7 +299,7 @@ drm_intel_bo_madvise(drm_intel_bo *bo, int madv)
return -1;
}
-int
+drm_public int
drm_intel_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
{
if (bo->bufmgr->bo_use_48b_address_range) {
@@ -314,13 +310,13 @@ drm_intel_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
return -ENODEV;
}
-int
+drm_public int
drm_intel_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
{
return bo->bufmgr->bo_references(bo, target_bo);
}
-int
+drm_public int
drm_intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id)
{
if (bufmgr->get_pipe_from_crtc_id)
@@ -364,7 +360,7 @@ drm_intel_probe_agp_aperture_size(int fd)
}
#endif
-int
+drm_public int
drm_intel_get_aperture_sizes(int fd, size_t *mappable, size_t *total)
{
diff --git a/intel/intel_bufmgr_fake.c b/intel/intel_bufmgr_fake.c
index 641df6a1..0cec51f5 100644
--- a/intel/intel_bufmgr_fake.c
+++ b/intel/intel_bufmgr_fake.c
@@ -34,10 +34,6 @@
* the bugs in the old texture manager.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <string.h>
#include <assert.h>
@@ -245,7 +241,7 @@ FENCE_LTE(unsigned a, unsigned b)
return 0;
}
-void
+drm_public void
drm_intel_bufmgr_fake_set_fence_callback(drm_intel_bufmgr *bufmgr,
unsigned int (*emit) (void *priv),
void (*wait) (unsigned int fence,
@@ -768,7 +764,7 @@ drm_intel_fake_bo_wait_rendering(drm_intel_bo *bo)
* -- just evict everything
* -- and wait for idle
*/
-void
+drm_public void
drm_intel_bufmgr_fake_contended_lock_take(drm_intel_bufmgr *bufmgr)
{
drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
@@ -864,7 +860,7 @@ drm_intel_fake_bo_alloc_tiled(drm_intel_bufmgr * bufmgr,
4096);
}
-drm_intel_bo *
+drm_public drm_intel_bo *
drm_intel_bo_fake_alloc_static(drm_intel_bufmgr *bufmgr,
const char *name,
unsigned long offset,
@@ -959,7 +955,7 @@ drm_intel_fake_bo_unreference(drm_intel_bo *bo)
* Set the buffer as not requiring backing store, and instead get the callback
* invoked whenever it would be set dirty.
*/
-void
+drm_public void
drm_intel_bo_fake_disable_backing_store(drm_intel_bo *bo,
void (*invalidate_cb) (drm_intel_bo *bo,
void *ptr),
@@ -1413,7 +1409,7 @@ drm_intel_bo_fake_post_submit(drm_intel_bo *bo)
bo_fake->write_domain = 0;
}
-void
+drm_public void
drm_intel_bufmgr_fake_set_exec_callback(drm_intel_bufmgr *bufmgr,
int (*exec) (drm_intel_bo *bo,
unsigned int used,
@@ -1536,7 +1532,7 @@ drm_intel_fake_check_aperture_space(drm_intel_bo ** bo_array, int count)
* Used by the X Server on LeaveVT, when the card memory is no longer our
* own.
*/
-void
+drm_public void
drm_intel_bufmgr_fake_evict_all(drm_intel_bufmgr *bufmgr)
{
drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
@@ -1571,7 +1567,7 @@ drm_intel_bufmgr_fake_evict_all(drm_intel_bufmgr *bufmgr)
pthread_mutex_unlock(&bufmgr_fake->lock);
}
-void
+drm_public void
drm_intel_bufmgr_fake_set_last_dispatch(drm_intel_bufmgr *bufmgr,
volatile unsigned int
*last_dispatch)
@@ -1581,7 +1577,7 @@ drm_intel_bufmgr_fake_set_last_dispatch(drm_intel_bufmgr *bufmgr,
bufmgr_fake->last_dispatch = (volatile int *)last_dispatch;
}
-drm_intel_bufmgr *
+drm_public drm_intel_bufmgr *
drm_intel_bufmgr_fake_init(int fd, unsigned long low_offset,
void *low_virtual, unsigned long size,
volatile unsigned int *last_dispatch)
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index a6656003..fbf48730 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -34,10 +34,6 @@
* Dave Airlie <airlied@linux.ie>
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <xf86drm.h>
#include <xf86atomic.h>
#include <fcntl.h>
@@ -66,7 +62,7 @@
#include "i915_drm.h"
#include "uthash.h"
-#ifdef HAVE_VALGRIND
+#if HAVE_VALGRIND
#include <valgrind.h>
#include <memcheck.h>
#define VG(x) x
@@ -270,20 +266,6 @@ struct _drm_intel_bo_gem {
bool is_userptr;
/**
- * Boolean of whether this buffer can be placed in the full 48-bit
- * address range on gen8+.
- *
- * By default, buffers will be keep in a 32-bit range, unless this
- * flag is explicitly set.
- */
- bool use_48b_address_range;
-
- /**
- * Whether this buffer is softpinned at offset specified by the user
- */
- bool is_softpin;
-
- /**
* Size in bytes of this buffer and its relocation descendents.
*
* Used to avoid costly tree walking in
@@ -438,7 +420,7 @@ drm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
if (bo_gem->relocs == NULL && bo_gem->softpin_target == NULL) {
DBG("%2d: %d %s(%s)\n", i, bo_gem->gem_handle,
- bo_gem->is_softpin ? "*" : "",
+ bo_gem->kflags & EXEC_OBJECT_PINNED ? "*" : "",
bo_gem->name);
continue;
}
@@ -452,7 +434,7 @@ drm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
"%d (%s)@0x%08x %08x + 0x%08x\n",
i,
bo_gem->gem_handle,
- bo_gem->is_softpin ? "*" : "",
+ bo_gem->kflags & EXEC_OBJECT_PINNED ? "*" : "",
bo_gem->name,
upper_32_bits(bo_gem->relocs[j].offset),
lower_32_bits(bo_gem->relocs[j].offset),
@@ -471,7 +453,7 @@ drm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
"%d *(%s)@0x%08x %08x\n",
i,
bo_gem->gem_handle,
- bo_gem->is_softpin ? "*" : "",
+ bo_gem->kflags & EXEC_OBJECT_PINNED ? "*" : "",
bo_gem->name,
target_gem->gem_handle,
target_gem->name,
@@ -541,14 +523,11 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
int index;
- int flags = 0;
+ unsigned long flags;
+ flags = 0;
if (need_fence)
flags |= EXEC_OBJECT_NEEDS_FENCE;
- if (bo_gem->use_48b_address_range)
- flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
- if (bo_gem->is_softpin)
- flags |= EXEC_OBJECT_PINNED;
if (bo_gem->validate_index != -1) {
bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |= flags;
@@ -579,7 +558,7 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
bufmgr_gem->exec2_objects[index].relocs_ptr = (uintptr_t)bo_gem->relocs;
bufmgr_gem->exec2_objects[index].alignment = bo->align;
bufmgr_gem->exec2_objects[index].offset = bo->offset64;
- bufmgr_gem->exec2_objects[index].flags = flags | bo_gem->kflags;
+ bufmgr_gem->exec2_objects[index].flags = bo_gem->kflags | flags;
bufmgr_gem->exec2_objects[index].rsvd1 = 0;
bufmgr_gem->exec2_objects[index].rsvd2 = 0;
bufmgr_gem->exec_bos[index] = bo;
@@ -676,7 +655,6 @@ drm_intel_gem_bo_busy(drm_intel_bo *bo)
} else {
return false;
}
- return (ret == 0 && busy.busy);
}
static int
@@ -832,6 +810,10 @@ retry:
}
bo_gem->gem_handle = create.handle;
+ HASH_ADD(handle_hh, bufmgr_gem->handle_table,
+ gem_handle, sizeof(bo_gem->gem_handle),
+ bo_gem);
+
bo_gem->bo.handle = bo_gem->gem_handle;
bo_gem->bo.bufmgr = bufmgr;
bo_gem->bo.align = alignment;
@@ -844,10 +826,6 @@ retry:
tiling_mode,
stride))
goto err_free;
-
- HASH_ADD(handle_hh, bufmgr_gem->handle_table,
- gem_handle, sizeof(bo_gem->gem_handle),
- bo_gem);
}
bo_gem->name = name;
@@ -857,7 +835,6 @@ retry:
bo_gem->used_as_reloc_target = false;
bo_gem->has_error = false;
bo_gem->reusable = true;
- bo_gem->use_48b_address_range = false;
drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, alignment);
pthread_mutex_unlock(&bufmgr_gem->lock);
@@ -1016,7 +993,6 @@ drm_intel_gem_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
bo_gem->used_as_reloc_target = false;
bo_gem->has_error = false;
bo_gem->reusable = false;
- bo_gem->use_48b_address_range = false;
drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
pthread_mutex_unlock(&bufmgr_gem->lock);
@@ -1099,7 +1075,7 @@ check_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
* This can be used when one application needs to pass a buffer object
* to another.
*/
-drm_intel_bo *
+drm_public drm_intel_bo *
drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
const char *name,
unsigned int handle)
@@ -1164,7 +1140,6 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
bo_gem->bo.handle = open_arg.handle;
bo_gem->global_name = handle;
bo_gem->reusable = false;
- bo_gem->use_48b_address_range = false;
HASH_ADD(handle_hh, bufmgr_gem->handle_table,
gem_handle, sizeof(bo_gem->gem_handle), bo_gem);
@@ -1411,8 +1386,6 @@ drm_intel_gem_bo_unreference_final(drm_intel_bo *bo, time_t time)
bo_gem->name = NULL;
bo_gem->validate_index = -1;
- bo_gem->kflags = 0;
-
DRMLISTADDTAIL(&bo_gem->head, &bucket->head);
} else {
drm_intel_gem_bo_free(bo);
@@ -1589,7 +1562,7 @@ map_gtt(drm_intel_bo *bo)
return 0;
}
-int
+drm_public int
drm_intel_gem_bo_map_gtt(drm_intel_bo *bo)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1648,11 +1621,11 @@ drm_intel_gem_bo_map_gtt(drm_intel_bo *bo)
* undefined).
*/
-int
+drm_public int
drm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
-#ifdef HAVE_VALGRIND
+#if HAVE_VALGRIND
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
#endif
int ret;
@@ -1737,7 +1710,7 @@ static int drm_intel_gem_bo_unmap(drm_intel_bo *bo)
return ret;
}
-int
+drm_public int
drm_intel_gem_bo_unmap_gtt(drm_intel_bo *bo)
{
return drm_intel_gem_bo_unmap(bo);
@@ -1862,7 +1835,7 @@ drm_intel_gem_bo_wait_rendering(drm_intel_bo *bo)
* Note that some kernels have broken the inifite wait for negative values
* promise, upgrade to latest stable kernels if this is the case.
*/
-int
+drm_public int
drm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1898,7 +1871,7 @@ drm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns)
* In combination with drm_intel_gem_bo_pin() and manual fence management, we
* can do tiled pixmaps this way.
*/
-void
+drm_public void
drm_intel_gem_bo_start_gtt_access(drm_intel_bo *bo, int write_enable)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -2054,7 +2027,11 @@ static void
drm_intel_gem_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
- bo_gem->use_48b_address_range = enable;
+
+ if (enable)
+ bo_gem->kflags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+ else
+ bo_gem->kflags &= ~EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
}
static int
@@ -2071,7 +2048,7 @@ drm_intel_gem_bo_add_softpin_target(drm_intel_bo *bo, drm_intel_bo *target_bo)
return -ENOMEM;
}
- if (!target_bo_gem->is_softpin)
+ if (!(target_bo_gem->kflags & EXEC_OBJECT_PINNED))
return -EINVAL;
if (target_bo_gem == bo_gem)
return -EINVAL;
@@ -2103,7 +2080,7 @@ drm_intel_gem_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *)target_bo;
- if (target_bo_gem->is_softpin)
+ if (target_bo_gem->kflags & EXEC_OBJECT_PINNED)
return drm_intel_gem_bo_add_softpin_target(bo, target_bo);
else
return do_bo_emit_reloc(bo, offset, target_bo, target_offset,
@@ -2121,7 +2098,7 @@ drm_intel_gem_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
read_domains, write_domain, true);
}
-int
+drm_public int
drm_intel_gem_bo_get_reloc_count(drm_intel_bo *bo)
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -2144,7 +2121,7 @@ drm_intel_gem_bo_get_reloc_count(drm_intel_bo *bo)
*
* This also removes all softpinned targets being referenced by the BO.
*/
-void
+drm_public void
drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -2287,7 +2264,7 @@ drm_intel_update_buffer_offsets2 (drm_intel_bufmgr_gem *bufmgr_gem)
/* If we're seeing softpinned object here it means that the kernel
* has relocated our object... Indicating a programming error
*/
- assert(!bo_gem->is_softpin);
+ assert(!(bo_gem->kflags & EXEC_OBJECT_PINNED));
DBG("BO %d (%s) migrated: 0x%08x %08x -> 0x%08x %08x\n",
bo_gem->gem_handle, bo_gem->name,
upper_32_bits(bo->offset64),
@@ -2300,7 +2277,7 @@ drm_intel_update_buffer_offsets2 (drm_intel_bufmgr_gem *bufmgr_gem)
}
}
-void
+drm_public void
drm_intel_gem_bo_aub_dump_bmp(drm_intel_bo *bo,
int x1, int y1, int width, int height,
enum aub_dump_bmp_format format,
@@ -2502,14 +2479,14 @@ drm_intel_gem_bo_mrb_exec2(drm_intel_bo *bo, int used,
-1, NULL, flags);
}
-int
+drm_public int
drm_intel_gem_bo_context_exec(drm_intel_bo *bo, drm_intel_context *ctx,
int used, unsigned int flags)
{
return do_exec2(bo, used, ctx, NULL, 0, 0, -1, NULL, flags);
}
-int
+drm_public int
drm_intel_gem_bo_fence_exec(drm_intel_bo *bo,
drm_intel_context *ctx,
int used,
@@ -2643,13 +2620,14 @@ drm_intel_gem_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset)
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
- bo_gem->is_softpin = true;
bo->offset64 = offset;
bo->offset = offset;
+ bo_gem->kflags |= EXEC_OBJECT_PINNED;
+
return 0;
}
-drm_intel_bo *
+drm_public drm_intel_bo *
drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int size)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
@@ -2709,7 +2687,6 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
bo_gem->used_as_reloc_target = false;
bo_gem->has_error = false;
bo_gem->reusable = false;
- bo_gem->use_48b_address_range = false;
memclear(get_tiling);
get_tiling.handle = bo_gem->gem_handle;
@@ -2733,7 +2710,7 @@ err:
return NULL;
}
-int
+drm_public int
drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -2785,7 +2762,7 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
* size is only bounded by how many buffers of that size we've managed to have
* in flight at once.
*/
-void
+drm_public void
drm_intel_bufmgr_gem_enable_reuse(drm_intel_bufmgr *bufmgr)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
@@ -2807,7 +2784,7 @@ drm_intel_bufmgr_gem_enable_reuse(drm_intel_bufmgr *bufmgr)
* which can be checked using drm_intel_bufmgr_can_disable_implicit_sync,
* or subsequent execbufs involving the bo will generate EINVAL.
*/
-void
+drm_public void
drm_intel_gem_bo_disable_implicit_sync(drm_intel_bo *bo)
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -2826,7 +2803,7 @@ drm_intel_gem_bo_disable_implicit_sync(drm_intel_bo *bo)
* function can be used to restore the implicit sync before subsequent
* rendering.
*/
-void
+drm_public void
drm_intel_gem_bo_enable_implicit_sync(drm_intel_bo *bo)
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -2838,7 +2815,7 @@ drm_intel_gem_bo_enable_implicit_sync(drm_intel_bo *bo)
* Query whether the kernel supports disabling of its implicit synchronisation
* before execbuf. See drm_intel_gem_bo_disable_implicit_sync()
*/
-int
+drm_public int
drm_intel_bufmgr_gem_can_disable_implicit_sync(drm_intel_bufmgr *bufmgr)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
@@ -2853,7 +2830,7 @@ drm_intel_bufmgr_gem_can_disable_implicit_sync(drm_intel_bufmgr *bufmgr)
* allocation. If this option is not enabled, all relocs will have fence
* register allocated.
*/
-void
+drm_public void
drm_intel_bufmgr_gem_enable_fenced_relocs(drm_intel_bufmgr *bufmgr)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3132,7 +3109,7 @@ init_cache_buckets(drm_intel_bufmgr_gem *bufmgr_gem)
}
}
-void
+drm_public void
drm_intel_bufmgr_gem_set_vma_cache_size(drm_intel_bufmgr *bufmgr, int limit)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3201,7 +3178,7 @@ get_pci_device_id(drm_intel_bufmgr_gem *bufmgr_gem)
return devid;
}
-int
+drm_public int
drm_intel_bufmgr_gem_get_devid(drm_intel_bufmgr *bufmgr)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3215,7 +3192,7 @@ drm_intel_bufmgr_gem_get_devid(drm_intel_bufmgr *bufmgr)
* This function has to be called before drm_intel_bufmgr_gem_set_aub_dump()
* for it to have any effect.
*/
-void
+drm_public void
drm_intel_bufmgr_gem_set_aub_filename(drm_intel_bufmgr *bufmgr,
const char *filename)
{
@@ -3229,7 +3206,7 @@ drm_intel_bufmgr_gem_set_aub_filename(drm_intel_bufmgr *bufmgr,
* You can set up a GTT and upload your objects into the referenced
* space, then send off batchbuffers and get BMPs out the other end.
*/
-void
+drm_public void
drm_intel_bufmgr_gem_set_aub_dump(drm_intel_bufmgr *bufmgr, int enable)
{
fprintf(stderr, "libdrm aub dumping is deprecated.\n\n"
@@ -3239,7 +3216,7 @@ drm_intel_bufmgr_gem_set_aub_dump(drm_intel_bufmgr *bufmgr, int enable)
"See the intel_aubdump man page for more details.\n");
}
-drm_intel_context *
+drm_public drm_intel_context *
drm_intel_gem_context_create(drm_intel_bufmgr *bufmgr)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3266,7 +3243,7 @@ drm_intel_gem_context_create(drm_intel_bufmgr *bufmgr)
return context;
}
-int
+drm_public int
drm_intel_gem_context_get_id(drm_intel_context *ctx, uint32_t *ctx_id)
{
if (ctx == NULL)
@@ -3277,7 +3254,7 @@ drm_intel_gem_context_get_id(drm_intel_context *ctx, uint32_t *ctx_id)
return 0;
}
-void
+drm_public void
drm_intel_gem_context_destroy(drm_intel_context *ctx)
{
drm_intel_bufmgr_gem *bufmgr_gem;
@@ -3300,7 +3277,7 @@ drm_intel_gem_context_destroy(drm_intel_context *ctx)
free(ctx);
}
-int
+drm_public int
drm_intel_get_reset_stats(drm_intel_context *ctx,
uint32_t *reset_count,
uint32_t *active,
@@ -3334,7 +3311,7 @@ drm_intel_get_reset_stats(drm_intel_context *ctx,
return ret;
}
-int
+drm_public int
drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
uint32_t offset,
uint64_t *result)
@@ -3352,7 +3329,7 @@ drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
return ret;
}
-int
+drm_public int
drm_intel_get_subslice_total(int fd, unsigned int *subslice_total)
{
drm_i915_getparam_t gp;
@@ -3368,7 +3345,7 @@ drm_intel_get_subslice_total(int fd, unsigned int *subslice_total)
return 0;
}
-int
+drm_public int
drm_intel_get_eu_total(int fd, unsigned int *eu_total)
{
drm_i915_getparam_t gp;
@@ -3384,7 +3361,7 @@ drm_intel_get_eu_total(int fd, unsigned int *eu_total)
return 0;
}
-int
+drm_public int
drm_intel_get_pooled_eu(int fd)
{
drm_i915_getparam_t gp;
@@ -3399,7 +3376,7 @@ drm_intel_get_pooled_eu(int fd)
return ret;
}
-int
+drm_public int
drm_intel_get_min_eu_in_pool(int fd)
{
drm_i915_getparam_t gp;
@@ -3435,8 +3412,7 @@ drm_intel_get_min_eu_in_pool(int fd)
* default state (no annotations), call this function with a \c count
* of zero.
*/
-void
-drm_intel_bufmgr_gem_set_aub_annotations(drm_intel_bo *bo,
+drm_public void drm_intel_bufmgr_gem_set_aub_annotations(drm_intel_bo *bo,
drm_intel_aub_annotation *annotations,
unsigned count)
{
@@ -3477,7 +3453,7 @@ drm_intel_bufmgr_gem_unref(drm_intel_bufmgr *bufmgr)
}
}
-void *drm_intel_gem_bo_map__gtt(drm_intel_bo *bo)
+drm_public void *drm_intel_gem_bo_map__gtt(drm_intel_bo *bo)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -3525,7 +3501,7 @@ void *drm_intel_gem_bo_map__gtt(drm_intel_bo *bo)
return bo_gem->gtt_virtual;
}
-void *drm_intel_gem_bo_map__cpu(drm_intel_bo *bo)
+drm_public void *drm_intel_gem_bo_map__cpu(drm_intel_bo *bo)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -3569,7 +3545,7 @@ void *drm_intel_gem_bo_map__cpu(drm_intel_bo *bo)
return bo_gem->mem_virtual;
}
-void *drm_intel_gem_bo_map__wc(drm_intel_bo *bo)
+drm_public void *drm_intel_gem_bo_map__wc(drm_intel_bo *bo)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -3618,7 +3594,7 @@ void *drm_intel_gem_bo_map__wc(drm_intel_bo *bo)
*
* \param fd File descriptor of the opened DRM device.
*/
-drm_intel_bufmgr *
+drm_public drm_intel_bufmgr *
drm_intel_bufmgr_gem_init(int fd, int batch_size)
{
drm_intel_bufmgr_gem *bufmgr_gem;
@@ -3679,9 +3655,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
bufmgr_gem->gen = 7;
else if (IS_GEN8(bufmgr_gem->pci_device))
bufmgr_gem->gen = 8;
- else if (IS_GEN9(bufmgr_gem->pci_device))
- bufmgr_gem->gen = 9;
- else {
+ else if (!intel_get_genx(bufmgr_gem->pci_device, &bufmgr_gem->gen)) {
free(bufmgr_gem);
bufmgr_gem = NULL;
goto exit;
diff --git a/intel/intel_chipset.c b/intel/intel_chipset.c
new file mode 100644
index 00000000..5aa4a2f2
--- /dev/null
+++ b/intel/intel_chipset.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 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 (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 "intel_chipset.h"
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include "i915_pciids.h"
+
+#undef INTEL_VGA_DEVICE
+#define INTEL_VGA_DEVICE(id, gen) { id, gen }
+
+static const struct pci_device {
+ uint16_t device;
+ uint16_t gen;
+} pciids[] = {
+ /* Keep ids sorted by gen; latest gen first */
+ INTEL_ICL_11_IDS(11),
+ INTEL_CNL_IDS(10),
+ INTEL_CFL_IDS(9),
+ INTEL_GLK_IDS(9),
+ INTEL_KBL_IDS(9),
+ INTEL_BXT_IDS(9),
+ INTEL_SKL_IDS(9),
+};
+
+drm_private bool intel_is_genx(unsigned int devid, int gen)
+{
+ const struct pci_device *p,
+ *pend = pciids + sizeof(pciids) / sizeof(pciids[0]);
+
+ for (p = pciids; p < pend; p++) {
+ /* PCI IDs are sorted */
+ if (p->gen < gen)
+ break;
+
+ if (p->device != devid)
+ continue;
+
+ if (gen == p->gen)
+ return true;
+
+ break;
+ }
+
+ return false;
+}
+
+drm_private bool intel_get_genx(unsigned int devid, int *gen)
+{
+ const struct pci_device *p,
+ *pend = pciids + sizeof(pciids) / sizeof(pciids[0]);
+
+ for (p = pciids; p < pend; p++) {
+ if (p->device != devid)
+ continue;
+
+ if (gen)
+ *gen = p->gen;
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
index 41fc0da0..5db207cc 100644
--- a/intel/intel_chipset.h
+++ b/intel/intel_chipset.h
@@ -165,61 +165,8 @@
#define PCI_CHIP_CHERRYVIEW_2 0x22b2
#define PCI_CHIP_CHERRYVIEW_3 0x22b3
-#define PCI_CHIP_SKYLAKE_DT_GT1 0x1902
-#define PCI_CHIP_SKYLAKE_ULT_GT1 0x1906
-#define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A /* Reserved */
-#define PCI_CHIP_SKYLAKE_H_GT1 0x190B
-#define PCI_CHIP_SKYLAKE_ULX_GT1 0x190E /* Reserved */
#define PCI_CHIP_SKYLAKE_DT_GT2 0x1912
-#define PCI_CHIP_SKYLAKE_FUSED0_GT2 0x1913 /* Reserved */
-#define PCI_CHIP_SKYLAKE_FUSED1_GT2 0x1915 /* Reserved */
-#define PCI_CHIP_SKYLAKE_ULT_GT2 0x1916
-#define PCI_CHIP_SKYLAKE_FUSED2_GT2 0x1917 /* Reserved */
-#define PCI_CHIP_SKYLAKE_SRV_GT2 0x191A /* Reserved */
-#define PCI_CHIP_SKYLAKE_HALO_GT2 0x191B
-#define PCI_CHIP_SKYLAKE_WKS_GT2 0x191D
-#define PCI_CHIP_SKYLAKE_ULX_GT2 0x191E
-#define PCI_CHIP_SKYLAKE_MOBILE_GT2 0x1921 /* Reserved */
-#define PCI_CHIP_SKYLAKE_ULT_GT3_0 0x1923
-#define PCI_CHIP_SKYLAKE_ULT_GT3_1 0x1926
-#define PCI_CHIP_SKYLAKE_ULT_GT3_2 0x1927
-#define PCI_CHIP_SKYLAKE_SRV_GT4 0x192A
-#define PCI_CHIP_SKYLAKE_HALO_GT3 0x192B /* Reserved */
-#define PCI_CHIP_SKYLAKE_SRV_GT3 0x192D
-#define PCI_CHIP_SKYLAKE_DT_GT4 0x1932
-#define PCI_CHIP_SKYLAKE_SRV_GT4X 0x193A
-#define PCI_CHIP_SKYLAKE_H_GT4 0x193B
-#define PCI_CHIP_SKYLAKE_WKS_GT4 0x193D
-
-#define PCI_CHIP_KABYLAKE_ULT_GT2 0x5916
-#define PCI_CHIP_KABYLAKE_ULT_GT1_5 0x5913
-#define PCI_CHIP_KABYLAKE_ULT_GT1 0x5906
-#define PCI_CHIP_KABYLAKE_ULT_GT3_0 0x5923
-#define PCI_CHIP_KABYLAKE_ULT_GT3_1 0x5926
-#define PCI_CHIP_KABYLAKE_ULT_GT3_2 0x5927
-#define PCI_CHIP_KABYLAKE_ULT_GT2F 0x5921
-#define PCI_CHIP_KABYLAKE_ULX_GT1_5 0x5915
-#define PCI_CHIP_KABYLAKE_ULX_GT1 0x590E
-#define PCI_CHIP_KABYLAKE_ULX_GT2 0x591E
#define PCI_CHIP_KABYLAKE_DT_GT2 0x5912
-#define PCI_CHIP_KABYLAKE_DT_GT1_5 0x5917
-#define PCI_CHIP_KABYLAKE_DT_GT1 0x5902
-#define PCI_CHIP_KABYLAKE_HALO_GT2 0x591B
-#define PCI_CHIP_KABYLAKE_HALO_GT4 0x593B
-#define PCI_CHIP_KABYLAKE_HALO_GT1_0 0x5908
-#define PCI_CHIP_KABYLAKE_HALO_GT1_1 0x590B
-#define PCI_CHIP_KABYLAKE_SRV_GT2 0x591A
-#define PCI_CHIP_KABYLAKE_SRV_GT1 0x590A
-#define PCI_CHIP_KABYLAKE_WKS_GT2 0x591D
-
-#define PCI_CHIP_BROXTON_0 0x0A84
-#define PCI_CHIP_BROXTON_1 0x1A84
-#define PCI_CHIP_BROXTON_2 0x5A84
-#define PCI_CHIP_BROXTON_3 0x1A85
-#define PCI_CHIP_BROXTON_4 0x5A85
-
-#define PCI_CHIP_GLK 0x3184
-#define PCI_CHIP_GLK_2X6 0x3185
#define IS_MOBILE(devid) ((devid) == PCI_CHIP_I855_GM || \
(devid) == PCI_CHIP_I915_GM || \
@@ -380,82 +327,16 @@
#define IS_GEN8(devid) (IS_BROADWELL(devid) || \
IS_CHERRYVIEW(devid))
-#define IS_SKL_GT1(devid) ((devid) == PCI_CHIP_SKYLAKE_DT_GT1 || \
- (devid) == PCI_CHIP_SKYLAKE_ULT_GT1 || \
- (devid) == PCI_CHIP_SKYLAKE_SRV_GT1 || \
- (devid) == PCI_CHIP_SKYLAKE_H_GT1 || \
- (devid) == PCI_CHIP_SKYLAKE_ULX_GT1)
-
-#define IS_SKL_GT2(devid) ((devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_FUSED0_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_FUSED1_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_ULT_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_FUSED2_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_SRV_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_HALO_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_WKS_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_ULX_GT2 || \
- (devid) == PCI_CHIP_SKYLAKE_MOBILE_GT2)
-
-#define IS_SKL_GT3(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT3_0 || \
- (devid) == PCI_CHIP_SKYLAKE_ULT_GT3_1 || \
- (devid) == PCI_CHIP_SKYLAKE_ULT_GT3_2 || \
- (devid) == PCI_CHIP_SKYLAKE_HALO_GT3 || \
- (devid) == PCI_CHIP_SKYLAKE_SRV_GT3)
-
-#define IS_SKL_GT4(devid) ((devid) == PCI_CHIP_SKYLAKE_SRV_GT4 || \
- (devid) == PCI_CHIP_SKYLAKE_DT_GT4 || \
- (devid) == PCI_CHIP_SKYLAKE_SRV_GT4X || \
- (devid) == PCI_CHIP_SKYLAKE_H_GT4 || \
- (devid) == PCI_CHIP_SKYLAKE_WKS_GT4)
-
-#define IS_KBL_GT1(devid) ((devid) == PCI_CHIP_KABYLAKE_ULT_GT1_5 || \
- (devid) == PCI_CHIP_KABYLAKE_ULX_GT1_5 || \
- (devid) == PCI_CHIP_KABYLAKE_DT_GT1_5 || \
- (devid) == PCI_CHIP_KABYLAKE_ULT_GT1 || \
- (devid) == PCI_CHIP_KABYLAKE_ULX_GT1 || \
- (devid) == PCI_CHIP_KABYLAKE_DT_GT1 || \
- (devid) == PCI_CHIP_KABYLAKE_HALO_GT1_0 || \
- (devid) == PCI_CHIP_KABYLAKE_HALO_GT1_1 || \
- (devid) == PCI_CHIP_KABYLAKE_SRV_GT1)
-
-#define IS_KBL_GT2(devid) ((devid) == PCI_CHIP_KABYLAKE_ULT_GT2 || \
- (devid) == PCI_CHIP_KABYLAKE_ULT_GT2F || \
- (devid) == PCI_CHIP_KABYLAKE_ULX_GT2 || \
- (devid) == PCI_CHIP_KABYLAKE_DT_GT2 || \
- (devid) == PCI_CHIP_KABYLAKE_HALO_GT2 || \
- (devid) == PCI_CHIP_KABYLAKE_SRV_GT2 || \
- (devid) == PCI_CHIP_KABYLAKE_WKS_GT2)
-
-#define IS_KBL_GT3(devid) ((devid) == PCI_CHIP_KABYLAKE_ULT_GT3_0 || \
- (devid) == PCI_CHIP_KABYLAKE_ULT_GT3_1 || \
- (devid) == PCI_CHIP_KABYLAKE_ULT_GT3_2)
-
-#define IS_KBL_GT4(devid) ((devid) == PCI_CHIP_KABYLAKE_HALO_GT4)
-
-#define IS_KABYLAKE(devid) (IS_KBL_GT1(devid) || \
- IS_KBL_GT2(devid) || \
- IS_KBL_GT3(devid) || \
- IS_KBL_GT4(devid))
-
-#define IS_SKYLAKE(devid) (IS_SKL_GT1(devid) || \
- IS_SKL_GT2(devid) || \
- IS_SKL_GT3(devid) || \
- IS_SKL_GT4(devid))
-
-#define IS_BROXTON(devid) ((devid) == PCI_CHIP_BROXTON_0 || \
- (devid) == PCI_CHIP_BROXTON_1 || \
- (devid) == PCI_CHIP_BROXTON_2 || \
- (devid) == PCI_CHIP_BROXTON_3 || \
- (devid) == PCI_CHIP_BROXTON_4)
-
-#define IS_GEMINILAKE(devid) ((devid) == PCI_CHIP_GLK || \
- (devid) == PCI_CHIP_GLK_2X6)
-
-#define IS_GEN9(devid) (IS_SKYLAKE(devid) || \
- IS_BROXTON(devid) || \
- IS_KABYLAKE(devid) || \
- IS_GEMINILAKE(devid))
+/* New platforms use kernel pci ids */
+#include <stdbool.h>
+#include <libdrm_macros.h>
+
+drm_private bool intel_is_genx(unsigned int devid, int gen);
+drm_private bool intel_get_genx(unsigned int devid, int *gen);
+
+#define IS_GEN9(devid) intel_is_genx(devid, 9)
+#define IS_GEN10(devid) intel_is_genx(devid, 10)
+#define IS_GEN11(devid) intel_is_genx(devid, 11)
#define IS_9XX(dev) (IS_GEN3(dev) || \
IS_GEN4(dev) || \
@@ -463,7 +344,6 @@
IS_GEN6(dev) || \
IS_GEN7(dev) || \
IS_GEN8(dev) || \
- IS_GEN9(dev))
-
+ intel_get_genx(dev, NULL))
#endif /* _INTEL_CHIPSET_H */
diff --git a/intel/intel_decode.c b/intel/intel_decode.c
index 803d2029..e0a51664 100644
--- a/intel/intel_decode.c
+++ b/intel/intel_decode.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
@@ -3815,7 +3811,7 @@ decode_3d_i830(struct drm_intel_decode *ctx)
return 1;
}
-struct drm_intel_decode *
+drm_public struct drm_intel_decode *
drm_intel_decode_context_alloc(uint32_t devid)
{
struct drm_intel_decode *ctx;
@@ -3827,8 +3823,8 @@ drm_intel_decode_context_alloc(uint32_t devid)
ctx->devid = devid;
ctx->out = stdout;
- if (IS_GEN9(devid))
- ctx->gen = 9;
+ if (intel_get_genx(devid, &ctx->gen))
+ ;
else if (IS_GEN8(devid))
ctx->gen = 8;
else if (IS_GEN7(devid))
@@ -3849,20 +3845,20 @@ drm_intel_decode_context_alloc(uint32_t devid)
return ctx;
}
-void
+drm_public void
drm_intel_decode_context_free(struct drm_intel_decode *ctx)
{
free(ctx);
}
-void
+drm_public void
drm_intel_decode_set_dump_past_end(struct drm_intel_decode *ctx,
int dump_past_end)
{
ctx->dump_past_end = !!dump_past_end;
}
-void
+drm_public void
drm_intel_decode_set_batch_pointer(struct drm_intel_decode *ctx,
void *data, uint32_t hw_offset, int count)
{
@@ -3871,7 +3867,7 @@ drm_intel_decode_set_batch_pointer(struct drm_intel_decode *ctx,
ctx->base_count = count;
}
-void
+drm_public void
drm_intel_decode_set_head_tail(struct drm_intel_decode *ctx,
uint32_t head, uint32_t tail)
{
@@ -3879,7 +3875,7 @@ drm_intel_decode_set_head_tail(struct drm_intel_decode *ctx,
ctx->tail = tail;
}
-void
+drm_public void
drm_intel_decode_set_output_file(struct drm_intel_decode *ctx,
FILE *output)
{
@@ -3893,13 +3889,13 @@ drm_intel_decode_set_output_file(struct drm_intel_decode *ctx,
* \param count number of DWORDs to decode in the batch buffer
* \param hw_offset hardware address for the buffer
*/
-void
+drm_public void
drm_intel_decode(struct drm_intel_decode *ctx)
{
int ret;
unsigned int index = 0;
uint32_t devid;
- int size = ctx->base_count * 4;
+ int size;
void *temp;
if (!ctx)
@@ -3909,6 +3905,7 @@ drm_intel_decode(struct drm_intel_decode *ctx)
* the batchbuffer. This lets us avoid a bunch of length
* checking in statically sized packets.
*/
+ size = ctx->base_count * 4;
temp = malloc(size + 4096);
memcpy(temp, ctx->base_data, size);
memset((char *)temp + size, 0xd0, 4096);
diff --git a/intel/meson.build b/intel/meson.build
new file mode 100644
index 00000000..3d6bbac6
--- /dev/null
+++ b/intel/meson.build
@@ -0,0 +1,106 @@
+# 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.
+
+libdrm_intel = shared_library(
+ 'drm_intel',
+ [
+ files(
+ 'intel_bufmgr.c', 'intel_bufmgr_fake.c', 'intel_bufmgr_gem.c',
+ 'intel_decode.c', 'mm.c', 'intel_chipset.c',
+ ),
+ config_file,
+ ],
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ dependencies : [dep_pciaccess, dep_pthread_stubs, dep_rt, dep_valgrind, dep_atomic_ops],
+ c_args : libdrm_c_args,
+ version : '1.0.0',
+ install : true,
+)
+
+ext_libdrm_intel = declare_dependency(
+ link_with : [libdrm, libdrm_intel],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+install_headers(
+ 'intel_bufmgr.h', 'intel_aub.h', 'intel_debug.h',
+ subdir : 'libdrm',
+)
+
+pkg.generate(
+ name : 'libdrm_intel',
+ libraries : libdrm_intel,
+ subdirs : ['.', 'libdrm'],
+ version : meson.project_version(),
+ requires : 'libdrm',
+ description : 'Userspace interface to intel kernel DRM services',
+)
+
+test_decode = executable(
+ 'test_decode',
+ files('test_decode.c'),
+ include_directories : [inc_root, inc_drm],
+ link_with : [libdrm, libdrm_intel],
+ c_args : libdrm_c_args,
+)
+
+test(
+ 'gen4-3d.batch',
+ prog_bash,
+ args : files('tests/gen4-3d.batch.sh'),
+ workdir : meson.current_build_dir(),
+)
+test(
+ 'gen45-3d.batch',
+ prog_bash,
+ args : files('tests/gm45-3d.batch.sh'),
+ workdir : meson.current_build_dir(),
+)
+test(
+ 'gen5-3d.batch',
+ prog_bash,
+ args : files('tests/gen5-3d.batch.sh'),
+ workdir : meson.current_build_dir(),
+)
+test(
+ 'gen6-3d.batch',
+ prog_bash,
+ args : files('tests/gen6-3d.batch.sh'),
+ workdir : meson.current_build_dir(),
+)
+test(
+ 'gen7-3d.batch',
+ prog_bash,
+ args : files('tests/gen7-3d.batch.sh'),
+ workdir : meson.current_build_dir(),
+)
+test(
+ 'gen7-2d-copy.batch',
+ prog_bash,
+ args : files('tests/gen7-2d-copy.batch.sh'),
+ workdir : meson.current_build_dir(),
+)
+test(
+ 'intel-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('intel-symbol-check'), libdrm_intel]
+)
diff --git a/intel/mm.c b/intel/mm.c
index 954e9dcb..79d8719d 100644
--- a/intel/mm.c
+++ b/intel/mm.c
@@ -22,10 +22,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <assert.h>
diff --git a/intel/mm.h b/intel/mm.h
index 8d83743f..1b0f84fc 100644
--- a/intel/mm.h
+++ b/intel/mm.h
@@ -29,10 +29,6 @@
#ifndef MM_H
#define MM_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "libdrm_macros.h"
struct mem_block {
diff --git a/intel/test_decode.c b/intel/test_decode.c
index b4eddcd1..b9f5b927 100644
--- a/intel/test_decode.c
+++ b/intel/test_decode.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -91,7 +87,7 @@ compare_batch(struct drm_intel_decode *ctx, const char *batch_filename)
{
FILE *out = NULL;
void *ptr, *ref_ptr, *batch_ptr;
-#ifdef HAVE_OPEN_MEMSTREAM
+#if HAVE_OPEN_MEMSTREAM
size_t size;
#endif
size_t ref_size, batch_size;
@@ -109,7 +105,7 @@ compare_batch(struct drm_intel_decode *ctx, const char *batch_filename)
* figure out how to output to a file in a safe and sane way
* inside of an automake project's test infrastructure.
*/
-#ifdef HAVE_OPEN_MEMSTREAM
+#if HAVE_OPEN_MEMSTREAM
out = open_memstream((char **)&ptr, &size);
#else
fprintf(stderr, "platform lacks open_memstream, skipping.\n");
diff --git a/libdrm_macros.h b/libdrm_macros.h
index b88fdcef..0dca8273 100644
--- a/libdrm_macros.h
+++ b/libdrm_macros.h
@@ -23,10 +23,12 @@
#ifndef LIBDRM_LIBDRM_H
#define LIBDRM_LIBDRM_H
-#if defined(HAVE_VISIBILITY)
+#if HAVE_VISIBILITY
# define drm_private __attribute__((visibility("hidden")))
+# define drm_public __attribute__((visibility("default")))
#else
# define drm_private
+# define drm_public
#endif
diff --git a/libkms/Makefile.am b/libkms/Makefile.am
index 461fc35b..ff4c1b2a 100644
--- a/libkms/Makefile.am
+++ b/libkms/Makefile.am
@@ -2,6 +2,7 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir)/include/drm \
-I$(top_srcdir)
@@ -39,5 +40,6 @@ libkmsinclude_HEADERS = $(LIBKMS_H_FILES)
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libkms.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = kms-symbol-check
EXTRA_DIST = $(TESTS)
diff --git a/libkms/api.c b/libkms/api.c
index 354d8a2e..caca1a87 100644
--- a/libkms/api.c
+++ b/libkms/api.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -37,12 +33,12 @@
#include "libdrm_macros.h"
#include "internal.h"
-int kms_create(int fd, struct kms_driver **out)
+drm_public int kms_create(int fd, struct kms_driver **out)
{
return linux_create(fd, out);
}
-int kms_get_prop(struct kms_driver *kms, unsigned key, unsigned *out)
+drm_public int kms_get_prop(struct kms_driver *kms, unsigned key, unsigned *out)
{
switch (key) {
case KMS_BO_TYPE:
@@ -53,7 +49,7 @@ int kms_get_prop(struct kms_driver *kms, unsigned key, unsigned *out)
return kms->get_prop(kms, key, out);
}
-int kms_destroy(struct kms_driver **kms)
+drm_public int kms_destroy(struct kms_driver **kms)
{
if (!(*kms))
return 0;
@@ -63,7 +59,7 @@ int kms_destroy(struct kms_driver **kms)
return 0;
}
-int kms_bo_create(struct kms_driver *kms, const unsigned *attr, struct kms_bo **out)
+drm_public int kms_bo_create(struct kms_driver *kms, const unsigned *attr, struct kms_bo **out)
{
unsigned width = 0;
unsigned height = 0;
@@ -101,7 +97,7 @@ int kms_bo_create(struct kms_driver *kms, const unsigned *attr, struct kms_bo **
return kms->bo_create(kms, width, height, type, attr, out);
}
-int kms_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out)
+drm_public int kms_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out)
{
switch (key) {
case KMS_PITCH:
@@ -117,17 +113,17 @@ int kms_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out)
return 0;
}
-int kms_bo_map(struct kms_bo *bo, void **out)
+drm_public int kms_bo_map(struct kms_bo *bo, void **out)
{
return bo->kms->bo_map(bo, out);
}
-int kms_bo_unmap(struct kms_bo *bo)
+drm_public int kms_bo_unmap(struct kms_bo *bo)
{
return bo->kms->bo_unmap(bo);
}
-int kms_bo_destroy(struct kms_bo **bo)
+drm_public int kms_bo_destroy(struct kms_bo **bo)
{
int ret;
diff --git a/libkms/dumb.c b/libkms/dumb.c
index b95a072c..17efc10a 100644
--- a/libkms/dumb.c
+++ b/libkms/dumb.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/exynos.c b/libkms/exynos.c
index 0e97fb51..ef64a668 100644
--- a/libkms/exynos.c
+++ b/libkms/exynos.c
@@ -5,16 +5,26 @@
* SooChan Lim <sc1.lim@samsung.com>
* Sangjin LEE <lsj119@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/intel.c b/libkms/intel.c
index 3d8ca055..859e7a0f 100644
--- a/libkms/intel.c
+++ b/libkms/intel.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/internal.h b/libkms/internal.h
index 905f5b17..8b386db6 100644
--- a/libkms/internal.h
+++ b/libkms/internal.h
@@ -29,10 +29,6 @@
#ifndef INTERNAL_H_
#define INTERNAL_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "libdrm_macros.h"
#include "libkms.h"
diff --git a/libkms/kms-symbol-check b/libkms/kms-symbol-check
index 658b2692..30f444f7 100755
--- a/libkms/kms-symbol-check
+++ b/libkms/kms-symbol-check
@@ -1,9 +1,11 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.sources/LIBKMS_H_FILES
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libkms.so} | awk '{print $3}'| while read func; do
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libkms.so} | awk '{print $3}'| while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
__bss_start
_edata
diff --git a/libkms/linux.c b/libkms/linux.c
index 0b50777e..56205054 100644
--- a/libkms/linux.c
+++ b/libkms/linux.c
@@ -29,10 +29,6 @@
* going from fd to pci id via fstat and udev.
*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -110,27 +106,27 @@ linux_from_sysfs(int fd, struct kms_driver **out)
if (ret)
return ret;
-#ifdef HAVE_INTEL
+#if HAVE_INTEL
if (!strcmp(name, "intel"))
ret = intel_create(fd, out);
else
#endif
-#ifdef HAVE_VMWGFX
+#if HAVE_VMWGFX
if (!strcmp(name, "vmwgfx"))
ret = vmwgfx_create(fd, out);
else
#endif
-#ifdef HAVE_NOUVEAU
+#if HAVE_NOUVEAU
if (!strcmp(name, "nouveau"))
ret = nouveau_create(fd, out);
else
#endif
-#ifdef HAVE_RADEON
+#if HAVE_RADEON
if (!strcmp(name, "radeon"))
ret = radeon_create(fd, out);
else
#endif
-#ifdef HAVE_EXYNOS
+#if HAVE_EXYNOS
if (!strcmp(name, "exynos"))
ret = exynos_create(fd, out);
else
diff --git a/libkms/meson.build b/libkms/meson.build
new file mode 100644
index 00000000..dc931608
--- /dev/null
+++ b/libkms/meson.build
@@ -0,0 +1,75 @@
+# 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 = shared_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],
+)
+
+install_headers('libkms.h', subdir : 'libkms')
+
+pkg.generate(
+ name : 'libkms',
+ libraries : libkms,
+ subdirs : ['libkms'],
+ version : '1.0.0',
+ requires_private : 'libdrm',
+ description : 'Library that abstracts away the different mm interfaces for kernel drivers',
+)
+
+test(
+ 'kms-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('kms-symbol-check'), libkms]
+)
diff --git a/libkms/nouveau.c b/libkms/nouveau.c
index d10e0fdb..7fe23db3 100644
--- a/libkms/nouveau.c
+++ b/libkms/nouveau.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/radeon.c b/libkms/radeon.c
index aaeeaf31..2cb2b11f 100644
--- a/libkms/radeon.c
+++ b/libkms/radeon.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/libkms/vmwgfx.c b/libkms/vmwgfx.c
index 6a24fd4d..f0e40be7 100644
--- a/libkms/vmwgfx.c
+++ b/libkms/vmwgfx.c
@@ -26,10 +26,6 @@
**************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdlib.h>
#include <string.h>
diff --git a/man/drm-kms.xml b/man/drm-kms.xml
index ae38dc8d..eb04c263 100644
--- a/man/drm-kms.xml
+++ b/man/drm-kms.xml
@@ -309,8 +309,8 @@ static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn)
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drm-memory.xml b/man/drm-memory.xml
index 6b4f0759..3aa7cf25 100644
--- a/man/drm-memory.xml
+++ b/man/drm-memory.xml
@@ -410,8 +410,8 @@ memset(map, 0, creq.size);
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drm.xml b/man/drm.xml
index 5a49fe13..1f559669 100644
--- a/man/drm.xml
+++ b/man/drm.xml
@@ -50,7 +50,7 @@
<para>In earlier days, the kernel framework was solely used to provide raw
hardware access to priviledged user-space processes which implement
- all the hardware abstraction layers. But more and more tasks where
+ all the hardware abstraction layers. But more and more tasks were
moved into the kernel. All these interfaces are based on
<citerefentry><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
commands on the DRM character device. The <emphasis>libdrm</emphasis>
@@ -119,8 +119,8 @@
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drmAvailable.xml b/man/drmAvailable.xml
index 55bef94a..1e5d7873 100644
--- a/man/drmAvailable.xml
+++ b/man/drmAvailable.xml
@@ -61,8 +61,8 @@
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drmHandleEvent.xml b/man/drmHandleEvent.xml
index b1006e51..83304428 100644
--- a/man/drmHandleEvent.xml
+++ b/man/drmHandleEvent.xml
@@ -86,8 +86,8 @@ typedef struct _drmEventContext {
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/drmModeGetResources.xml b/man/drmModeGetResources.xml
index 2f5e8c2c..0ab6a68b 100644
--- a/man/drmModeGetResources.xml
+++ b/man/drmModeGetResources.xml
@@ -116,8 +116,8 @@ typedef struct _drmModeRes {
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
- http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
- "libdrm" as the component.</para>
+ https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
+ under the "DRI" product, component "libdrm"</para>
</refsect1>
<refsect1>
diff --git a/man/meson.build b/man/meson.build
new file mode 100644
index 00000000..45eaeda0
--- /dev/null
+++ b/man/meson.build
@@ -0,0 +1,67 @@
+# 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.
+
+xsltproc_args = [
+ '--stringparam', 'man.authors.section.enabled', '0',
+ '--stringparam', 'man.copyright.section.enabled', '0',
+ '--stringparam', 'funcsynopsis.style', 'ansi',
+ '--stringparam', 'man.output.quietly', '1',
+ '--nonet', manpage_style,
+]
+
+xmls = [
+ ['drm', '7'], ['drm-kms', '7'], ['drm-memory', '7'], ['drmAvailable', '3'],
+ ['drmHandleEvent', '3'], ['drmModeGetResources', '3']
+]
+foreach x : xmls
+ m = x[0]
+ s = x[1]
+ custom_target(
+ m,
+ input : files('@0@.xml'.format(m)),
+ output : '@0@.@1@'.format(m, s),
+ command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT0@'],
+ install : true,
+ install_dir : join_paths(get_option('mandir'), 'man@0@'.format(s)),
+ build_by_default : true,
+ )
+endforeach
+
+foreach x : ['drm-mm', 'drm-gem', 'drm-ttm']
+ gen = custom_target(
+ 'gen-@0@'.format(x),
+ input : 'drm-memory.xml',
+ output : '@0@.xml'.format(x),
+ command : [
+ prog_sed, '-e', 's@^\.so \([a-z_]\+\)\.\([0-9]\)$$@\.so man\2\/\1\.\2@',
+ '@INPUT@',
+ ],
+ capture : true,
+ )
+ custom_target(
+ '@0@.7'.format(x),
+ input : gen,
+ output : '@0@.7'.format(x, '7'),
+ command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT@'],
+ install : true,
+ install_dir : join_paths(get_option('mandir'), 'man7'),
+ build_by_default : true,
+ )
+endforeach
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000..b3eb8467
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,386 @@
+# 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.
+
+project(
+ 'libdrm',
+ ['c'],
+ version : '2.4.97',
+ license : 'MIT',
+ meson_version : '>= 0.43',
+ default_options : ['buildtype=debugoptimized', 'c_std=gnu99'],
+)
+
+pkg = import('pkgconfig')
+
+config = configuration_data()
+
+config.set10('UDEV', get_option('udev'))
+with_freedreno_kgsl = get_option('freedreno-kgsl')
+with_install_tests = get_option('install-test-programs')
+
+if ['freebsd', 'dragonfly', 'netbsd'].contains(host_machine.system())
+ dep_pthread_stubs = dependency('pthread-stubs', version : '>= 0.4')
+else
+ dep_pthread_stubs = []
+endif
+dep_threads = dependency('threads')
+
+cc = meson.get_compiler('c')
+
+# Check for atomics
+intel_atomics = false
+lib_atomics = false
+
+dep_atomic_ops = dependency('atomic_ops', required : false)
+if cc.compiles('''
+ int atomic_add(int *i) { return __sync_add_and_fetch (i, 1); }
+ int atomic_cmpxchg(int *i, int j, int k) { return __sync_val_compare_and_swap (i, j, k); }
+ ''',
+ name : 'Intel Atomics')
+ intel_atomics = true
+ with_atomics = true
+ dep_atomic_ops = []
+elif dep_atomic_ops.found()
+ lib_atomics = true
+ with_atomics = true
+elif cc.has_function('atomic_cas_uint')
+ with_atomics = true
+else
+ with_atomics = false
+endif
+
+config.set10('HAVE_LIBDRM_ATOMIC_PRIMITIVES', intel_atomics)
+config.set10('HAVE_LIB_ATOMIC_OPS', lib_atomics)
+
+with_intel = false
+_intel = get_option('intel')
+if _intel != 'false'
+ if _intel == 'true' and not with_atomics
+ error('libdrm_intel requires atomics.')
+ else
+ with_intel = _intel == 'true' or host_machine.cpu_family().startswith('x86')
+ endif
+endif
+
+with_radeon = false
+_radeon = get_option('radeon')
+if _radeon != 'false'
+ if _radeon == 'true' and not with_atomics
+ error('libdrm_radeon requires atomics.')
+ endif
+ with_radeon = true
+endif
+
+with_amdgpu = false
+_amdgpu = get_option('amdgpu')
+if _amdgpu != 'false'
+ if _amdgpu == 'true' and not with_atomics
+ error('libdrm_amdgpu requires atomics.')
+ endif
+ with_amdgpu = true
+endif
+
+with_nouveau = false
+_nouveau = get_option('nouveau')
+if _nouveau != 'false'
+ if _nouveau == 'true' and not with_atomics
+ error('libdrm_nouveau requires atomics.')
+ endif
+ with_nouveau = true
+endif
+
+with_vmwgfx = false
+_vmwgfx = get_option('vmwgfx')
+if _vmwgfx != 'false'
+ with_vmwgfx = true
+endif
+
+with_omap = false
+_omap = get_option('omap')
+if _omap == 'true'
+ if not with_atomics
+ error('libdrm_omap requires atomics.')
+ endif
+ with_omap = true
+endif
+
+with_freedreno = false
+_freedreno = get_option('freedreno')
+if _freedreno != 'false'
+ if _freedreno == 'true' and not with_atomics
+ error('libdrm_freedreno requires atomics.')
+ else
+ with_freedreno = _freedreno == 'true' or ['arm', 'aarch64'].contains(host_machine.cpu_family())
+ endif
+endif
+
+with_tegra = false
+_tegra = get_option('tegra')
+if _tegra == 'true'
+ if not with_atomics
+ error('libdrm_tegra requires atomics.')
+ endif
+ with_tegra = true
+endif
+
+with_etnaviv = false
+_etnaviv = get_option('etnaviv')
+if _etnaviv == 'true'
+ if not with_atomics
+ error('libdrm_etnaviv requires atomics.')
+ endif
+ with_etnaviv = true
+endif
+
+with_exynos = get_option('exynos') == 'true'
+
+with_vc4 = false
+_vc4 = get_option('vc4')
+if _vc4 != 'false'
+ with_vc4 = _vc4 == 'true' or ['arm', 'aarch64'].contains(host_machine.cpu_family())
+endif
+
+# XXX: Aparently 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())
+endif
+
+# 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)
+else
+ dep_dl = []
+endif
+# clock_gettime might require -rt, or it might not. find out
+if not cc.has_function('clock_gettime', prefix : '#define _GNU_SOURCE\n#include <time.h>')
+ # XXX: untested
+ dep_rt = cc.find_library('rt')
+else
+ dep_rt = []
+endif
+dep_m = cc.find_library('m', required : false)
+foreach header : ['sys/sysctl.h', 'sys/select.h', 'alloca.h']
+ config.set('HAVE_' + header.underscorify().to_upper(),
+ cc.compiles('#include <@0@>'.format(header), name : '@0@ works'.format(header)))
+endforeach
+if cc.has_header_symbol('sys/sysmacros.h', 'major')
+ config.set10('MAJOR_IN_SYSMACROS', true)
+elif cc.has_header_symbol('sys/mkdev.h', 'major')
+ config.set10('MAJOR_IN_MKDEV', true)
+endif
+config.set10('HAVE_OPEN_MEMSTREAM', cc.has_function('open_memstream'))
+
+warn_c_args = []
+foreach a : ['-Wall', '-Wextra', '-Wsign-compare', '-Werror=undef',
+ '-Werror=implicit-function-declaration', '-Wpointer-arith',
+ '-Wwrite-strings', '-Wstrict-prototypes', '-Wmissing-prototypes',
+ '-Wmissing-declarations', '-Wnested-externs', '-Wpacked',
+ '-Wswitch-enum', '-Wmissing-format-attribute',
+ '-Wstrict-aliasing=2', '-Winit-self', '-Winline', '-Wshadow',
+ '-Wdeclaration-after-statement', '-Wold-style-definition']
+ if cc.has_argument(a)
+ warn_c_args += a
+ endif
+endforeach
+# GCC will never error for -Wno-*, so check for -W* then add -Wno-* to the list
+# of options
+foreach a : ['unused-parameter', 'attributes', 'long-long',
+ 'missing-field-initializers']
+ if cc.has_argument('-W@0@'.format(a))
+ warn_c_args += '-Wno-@0@'.format(a)
+ endif
+endforeach
+
+# all c args:
+libdrm_c_args = warn_c_args + ['-fvisibility=hidden']
+
+
+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'
+ dep_valgrind = dependency('valgrind', required : _valgrind == 'true')
+ with_valgrind = dep_valgrind.found()
+else
+ dep_valgrind = []
+ with_valgrind = false
+endif
+
+with_man_pages = get_option('man-pages')
+prog_xslt = find_program('xsltproc', required : with_man_pages == 'true')
+prog_sed = find_program('sed', required : with_man_pages == 'true')
+manpage_style = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
+if prog_xslt.found()
+ if run_command(prog_xslt, '--nonet', manpage_style).returncode() != 0
+ if with_man_pages == 'true'
+ error('Manpage style sheet cannot be found')
+ endif
+ with_man_pages = 'false'
+ endif
+endif
+with_man_pages = with_man_pages != 'false' and prog_xslt.found() and prog_sed.found()
+
+# Used for tets
+prog_bash = find_program('bash')
+
+config.set10('HAVE_VISIBILITY',
+ cc.compiles('''int foo_hidden(void) __attribute__((visibility(("hidden"))));''',
+ name : 'compiler supports __attribute__(("hidden"))'))
+
+foreach t : [
+ [with_exynos, 'EXYNOS'],
+ [with_freedreno_kgsl, 'FREEDRENO_KGSL'],
+ [with_intel, 'INTEL'],
+ [with_nouveau, 'NOUVEAU'],
+ [with_radeon, 'RADEON'],
+ [with_vc4, 'VC4'],
+ [with_vmwgfx, 'VMWGFX'],
+ [with_cairo_tests, 'CAIRO'],
+ [with_valgrind, 'VALGRIND'],
+ ]
+ config.set10('HAVE_@0@'.format(t[1]), t[0])
+endforeach
+if with_freedreno_kgsl and not with_freedreno
+ error('cannot enable freedreno-kgsl without freedreno support')
+endif
+config.set10('_GNU_SOURCE', true)
+config_file = configure_file(
+ configuration : config,
+ output : 'config.h',
+)
+add_project_arguments('-include', 'config.h', language : 'c')
+
+inc_root = include_directories('.')
+inc_drm = include_directories('include/drm')
+
+libdrm = shared_library(
+ 'drm',
+ [files(
+ 'xf86drm.c', 'xf86drmHash.c', 'xf86drmRandom.c', 'xf86drmSL.c',
+ 'xf86drmMode.c'
+ ),
+ config_file,
+ ],
+ c_args : libdrm_c_args,
+ dependencies : [dep_valgrind, dep_rt, dep_m],
+ include_directories : inc_drm,
+ version : '2.4.0',
+ install : true,
+)
+
+ext_libdrm = declare_dependency(
+ link_with : libdrm,
+ include_directories : [inc_root, inc_drm],
+)
+
+install_headers('libsync.h', 'xf86drm.h', 'xf86drmMode.h')
+install_headers(
+ 'include/drm/drm.h', 'include/drm/drm_fourcc.h', 'include/drm/drm_mode.h',
+ 'include/drm/drm_sarea.h', 'include/drm/i915_drm.h',
+ 'include/drm/mach64_drm.h', 'include/drm/mga_drm.h',
+ 'include/drm/msm_drm.h', 'include/drm/nouveau_drm.h',
+ 'include/drm/qxl_drm.h', 'include/drm/r128_drm.h',
+ 'include/drm/radeon_drm.h', 'include/drm/amdgpu_drm.h',
+ 'include/drm/savage_drm.h', 'include/drm/sis_drm.h',
+ 'include/drm/tegra_drm.h', 'include/drm/vc4_drm.h',
+ 'include/drm/via_drm.h', 'include/drm/virtgpu_drm.h',
+ subdir : 'libdrm',
+)
+if with_vmwgfx
+ install_headers('include/drm/vmwgfx_drm.h', subdir : 'libdrm')
+endif
+
+pkg.generate(
+ name : 'libdrm',
+ libraries : libdrm,
+ subdirs : ['.', 'libdrm'],
+ version : meson.project_version(),
+ description : 'Userspace interface to kernel DRM services',
+)
+
+env_test = environment()
+env_test.set('NM', find_program('nm').path())
+
+if with_libkms
+ subdir('libkms')
+endif
+if with_intel
+ subdir('intel')
+endif
+if with_nouveau
+ subdir('nouveau')
+endif
+if with_radeon
+ subdir('radeon')
+endif
+if with_amdgpu
+ subdir('amdgpu')
+endif
+if with_omap
+ subdir('omap')
+endif
+if with_exynos
+ subdir('exynos')
+endif
+if with_freedreno
+ subdir('freedreno')
+endif
+if with_tegra
+ subdir('tegra')
+endif
+if with_vc4
+ subdir('vc4')
+endif
+if with_etnaviv
+ subdir('etnaviv')
+endif
+if with_man_pages
+ subdir('man')
+endif
+subdir('data')
+subdir('tests')
+
+message('')
+message('@0@ will be compiled with:'.format(meson.project_name()))
+message('')
+message(' libkms @0@'.format(with_libkms))
+message(' Intel API @0@'.format(with_intel))
+message(' vmwgfx API @0@'.format(with_vmwgfx))
+message(' Radeon API @0@'.format(with_radeon))
+message(' AMDGPU API @0@'.format(with_amdgpu))
+message(' Nouveau API @0@'.format(with_nouveau))
+message(' OMAP API @0@'.format(with_omap))
+message(' EXYNOS API @0@'.format(with_exynos))
+message(' Freedreno API @0@ (kgsl: @1@)'.format(with_freedreno, with_freedreno_kgsl))
+message(' Tegra API @0@'.format(with_tegra))
+message(' VC4 API @0@'.format(with_vc4))
+message(' Etnaviv API @0@'.format(with_etnaviv))
+message('')
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..8af33f1c
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,143 @@
+# 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.
+
+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'],
+ description : '''Enable support for Intel's KMS API.''',
+)
+option(
+ 'radeon',
+ type : 'combo',
+ value : 'auto',
+ choices : ['true', 'false', 'auto'],
+ description : '''Enable support for radeons's KMS API.''',
+)
+option(
+ 'amdgpu',
+ type : 'combo',
+ value : 'auto',
+ choices : ['true', 'false', 'auto'],
+ description : '''Enable support for amdgpu's KMS API.''',
+)
+option(
+ 'nouveau',
+ type : 'combo',
+ value : 'auto',
+ choices : ['true', 'false', 'auto'],
+ description : '''Enable support for nouveau's KMS API.''',
+)
+option(
+ 'vmwgfx',
+ type : 'combo',
+ value : 'true',
+ choices : ['true', 'false', 'auto'],
+ description : '''Enable support for vmgfx's KMS API.''',
+)
+option(
+ 'omap',
+ type : 'combo',
+ value : 'false',
+ choices : ['true', 'false', 'auto'],
+ description : '''Enable support for OMAP's experimental KMS API.''',
+)
+option(
+ 'exynos',
+ type : 'combo',
+ value : 'false',
+ choices : ['true', 'false', 'auto'],
+ description : '''Enable support for EXYNOS's experimental KMS API.''',
+)
+option(
+ 'freedreno',
+ type : 'combo',
+ value : 'auto',
+ choices : ['true', 'false', 'auto'],
+ description : '''Enable support for freedreno's KMS API.''',
+)
+option(
+ 'tegra',
+ type : 'combo',
+ value : 'false',
+ choices : ['true', 'false', 'auto'],
+ description : '''Enable support for Tegra's experimental KMS API.''',
+)
+option(
+ 'vc4',
+ type : 'combo',
+ value : 'auto',
+ choices : ['true', 'false', 'auto'],
+ 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.''',
+)
+option(
+ 'cairo-tests',
+ type : 'combo',
+ value : 'auto',
+ choices : ['true', 'false', 'auto'],
+ description : 'Enable support for Cairo rendering in tests.',
+)
+option(
+ 'man-pages',
+ type : 'combo',
+ value : 'auto',
+ choices : ['true', 'false', 'auto'],
+ description : 'Enable manpage generation and installation.',
+)
+option(
+ 'valgrind',
+ type : 'combo',
+ value : 'auto',
+ choices : ['true', 'false', 'auto'],
+ description : 'Build libdrm with valgrind support.',
+)
+option(
+ 'freedreno-kgsl',
+ type : 'boolean',
+ value : false,
+ description : 'Enable support for freedreno to use downstream android kernel API.',
+)
+option(
+ 'install-test-programs',
+ type : 'boolean',
+ value : false,
+ description : 'Install test programs.',
+)
+option(
+ 'udev',
+ type : 'boolean',
+ value : false,
+ description : 'Enable support for using udev instead of mknod.',
+)
diff --git a/nouveau/Makefile.am b/nouveau/Makefile.am
index 344a8445..5574fd8f 100644
--- a/nouveau/Makefile.am
+++ b/nouveau/Makefile.am
@@ -2,6 +2,7 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm \
@@ -29,5 +30,6 @@ libdrm_nouveaunvifinclude_HEADERS = nvif/class.h \
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_nouveau.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = nouveau-symbol-check
EXTRA_DIST = $(TESTS)
diff --git a/nouveau/abi16.c b/nouveau/abi16.c
index ee38c0cb..ba2501ea 100644
--- a/nouveau/abi16.c
+++ b/nouveau/abi16.c
@@ -22,10 +22,6 @@
* Authors: Ben Skeggs
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
diff --git a/nouveau/bufctx.c b/nouveau/bufctx.c
index 4f76e5df..00924b3c 100644
--- a/nouveau/bufctx.c
+++ b/nouveau/bufctx.c
@@ -22,10 +22,6 @@
* Authors: Ben Skeggs
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -62,7 +58,7 @@ nouveau_bufctx(struct nouveau_bufctx *bctx)
return (struct nouveau_bufctx_priv *)bctx;
}
-int
+drm_public int
nouveau_bufctx_new(struct nouveau_client *client, int bins,
struct nouveau_bufctx **pbctx)
{
@@ -82,7 +78,7 @@ nouveau_bufctx_new(struct nouveau_client *client, int bins,
return -ENOMEM;
}
-void
+drm_public void
nouveau_bufctx_del(struct nouveau_bufctx **pbctx)
{
struct nouveau_bufctx_priv *pctx = nouveau_bufctx(*pbctx);
@@ -99,7 +95,7 @@ nouveau_bufctx_del(struct nouveau_bufctx **pbctx)
}
}
-void
+drm_public void
nouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin)
{
struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
@@ -117,7 +113,7 @@ nouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin)
pbin->relocs = 0;
}
-struct nouveau_bufref *
+drm_public struct nouveau_bufref *
nouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin,
struct nouveau_bo *bo, uint32_t flags)
{
@@ -144,7 +140,7 @@ nouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin,
return &pref->base;
}
-struct nouveau_bufref *
+drm_public struct nouveau_bufref *
nouveau_bufctx_mthd(struct nouveau_bufctx *bctx, int bin, uint32_t packet,
struct nouveau_bo *bo, uint64_t data, uint32_t flags,
uint32_t vor, uint32_t tor)
diff --git a/nouveau/meson.build b/nouveau/meson.build
new file mode 100644
index 00000000..0c1498d7
--- /dev/null
+++ b/nouveau/meson.build
@@ -0,0 +1,59 @@
+# 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.
+
+
+libdrm_nouveau = shared_library(
+ 'drm_nouveau',
+ [files( 'nouveau.c', 'pushbuf.c', 'bufctx.c', 'abi16.c'), config_file],
+ c_args : libdrm_c_args,
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ dependencies : [dep_threads, dep_atomic_ops],
+ version : '2.0.0',
+ install : true,
+)
+
+ext_libdrm_nouveau = declare_dependency(
+ link_with : [libdrm, libdrm_nouveau],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+install_headers('nouveau.h', subdir : 'libdrm/nouveau')
+install_headers(
+ 'nvif/class.h', 'nvif/cl0080.h', 'nvif/cl9097.h', 'nvif/if0002.h',
+ 'nvif/if0003.h', 'nvif/ioctl.h', 'nvif/unpack.h',
+ subdir : 'libdrm/nouveau/nvif'
+)
+
+pkg.generate(
+ name : 'libdrm_nouveau',
+ libraries : libdrm_nouveau,
+ subdirs : ['.', 'libdrm', 'libdrm/nouveau'],
+ version : meson.project_version(),
+ requires_private : 'libdrm',
+ description : 'Userspace interface to nouveau kernel DRM services',
+)
+
+test(
+ 'nouveau-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('nouveau-symbol-check'), libdrm_nouveau]
+)
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index b265cea4..6296244c 100755
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbol-check
@@ -1,9 +1,11 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.sources/LIBDRM_NOUVEAU_H_FILES
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_nouveau.so} | awk '{print $3}'| while read func; do
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_nouveau.so} | awk '{print $3}'| while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
__bss_start
_edata
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index e113a8fe..f18d1426 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -22,10 +22,6 @@
* Authors: Ben Skeggs
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -92,7 +88,7 @@ nouveau_object_ioctl(struct nouveau_object *obj, void *data, uint32_t size)
return drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NVIF, args, argc);
}
-int
+drm_public int
nouveau_object_mthd(struct nouveau_object *obj,
uint32_t mthd, void *data, uint32_t size)
{
@@ -127,14 +123,14 @@ nouveau_object_mthd(struct nouveau_object *obj,
return ret;
}
-void
+drm_public void
nouveau_object_sclass_put(struct nouveau_sclass **psclass)
{
free(*psclass);
*psclass = NULL;
}
-int
+drm_public int
nouveau_object_sclass_get(struct nouveau_object *obj,
struct nouveau_sclass **psclass)
{
@@ -184,7 +180,7 @@ nouveau_object_sclass_get(struct nouveau_object *obj,
return ret;
}
-int
+drm_public int
nouveau_object_mclass(struct nouveau_object *obj,
const struct nouveau_mclass *mclass)
{
@@ -286,7 +282,7 @@ nouveau_object_init(struct nouveau_object *parent, uint32_t handle,
return 0;
}
-int
+drm_public int
nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
uint32_t oclass, void *data, uint32_t length,
struct nouveau_object **pobj)
@@ -307,7 +303,7 @@ nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
return 0;
}
-void
+drm_public void
nouveau_object_del(struct nouveau_object **pobj)
{
struct nouveau_object *obj = *pobj;
@@ -318,14 +314,14 @@ nouveau_object_del(struct nouveau_object **pobj)
}
}
-void
+drm_public void
nouveau_drm_del(struct nouveau_drm **pdrm)
{
free(*pdrm);
*pdrm = NULL;
}
-int
+drm_public int
nouveau_drm_new(int fd, struct nouveau_drm **pdrm)
{
struct nouveau_drm *drm;
@@ -357,14 +353,14 @@ nouveau_drm_new(int fd, struct nouveau_drm **pdrm)
* is kept here to prevent AIGLX from crashing if the DDX is linked against
* the new libdrm, but the DRI driver against the old
*/
-int
+drm_public int
nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
drm_context_t ctx)
{
return -EACCES;
}
-int
+drm_public int
nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
void *data, uint32_t size, struct nouveau_device **pdev)
{
@@ -458,7 +454,7 @@ done:
return ret;
}
-int
+drm_public int
nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
{
struct nouveau_drm *drm;
@@ -486,7 +482,7 @@ nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
return 0;
}
-int
+drm_public int
nouveau_device_open(const char *busid, struct nouveau_device **pdev)
{
int ret = -ENODEV, fd = drmOpen("nouveau", busid);
@@ -498,7 +494,7 @@ nouveau_device_open(const char *busid, struct nouveau_device **pdev)
return ret;
}
-void
+drm_public void
nouveau_device_del(struct nouveau_device **pdev)
{
struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
@@ -517,7 +513,7 @@ nouveau_device_del(struct nouveau_device **pdev)
}
}
-int
+drm_public int
nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
{
struct nouveau_drm *drm = nouveau_drm(&dev->object);
@@ -528,7 +524,7 @@ nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
return ret;
}
-int
+drm_public int
nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value)
{
struct nouveau_drm *drm = nouveau_drm(&dev->object);
@@ -536,7 +532,7 @@ nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value)
return drmCommandWrite(drm->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r));
}
-int
+drm_public int
nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient)
{
struct nouveau_device_priv *nvdev = nouveau_device(dev);
@@ -575,7 +571,7 @@ unlock:
return ret;
}
-void
+drm_public void
nouveau_client_del(struct nouveau_client **pclient)
{
struct nouveau_client_priv *pcli = nouveau_client(*pclient);
@@ -622,7 +618,7 @@ nouveau_bo_del(struct nouveau_bo *bo)
free(nvbo);
}
-int
+drm_public int
nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align,
uint64_t size, union nouveau_bo_config *config,
struct nouveau_bo **pbo)
@@ -713,7 +709,7 @@ nouveau_bo_make_global(struct nouveau_bo_priv *nvbo)
}
}
-int
+drm_public int
nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
struct nouveau_bo **pbo)
{
@@ -725,7 +721,7 @@ nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
return ret;
}
-int
+drm_public int
nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
struct nouveau_bo **pbo)
{
@@ -754,7 +750,7 @@ nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
return ret;
}
-int
+drm_public int
nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
{
struct drm_gem_flink req = { .handle = bo->handle };
@@ -776,7 +772,7 @@ nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
return 0;
}
-void
+drm_public void
nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref)
{
struct nouveau_bo *ref = *pref;
@@ -790,7 +786,7 @@ nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref)
*pref = bo;
}
-int
+drm_public int
nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
struct nouveau_bo **bo)
{
@@ -810,7 +806,7 @@ nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
return ret;
}
-int
+drm_public int
nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd)
{
struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
@@ -825,7 +821,7 @@ nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd)
return 0;
}
-int
+drm_public int
nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
struct nouveau_client *client)
{
@@ -860,7 +856,7 @@ nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
return ret;
}
-int
+drm_public int
nouveau_bo_map(struct nouveau_bo *bo, uint32_t access,
struct nouveau_client *client)
{
diff --git a/nouveau/pushbuf.c b/nouveau/pushbuf.c
index 035e3019..e5f73f0d 100644
--- a/nouveau/pushbuf.c
+++ b/nouveau/pushbuf.c
@@ -22,10 +22,6 @@
* Authors: Ben Skeggs
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -532,7 +528,7 @@ pushbuf_validate(struct nouveau_pushbuf *push, bool retry)
return ret;
}
-int
+drm_public int
nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan,
int nr, uint32_t size, bool immediate,
struct nouveau_pushbuf **ppush)
@@ -603,7 +599,7 @@ nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan,
return 0;
}
-void
+drm_public void
nouveau_pushbuf_del(struct nouveau_pushbuf **ppush)
{
struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(*ppush);
@@ -629,7 +625,7 @@ nouveau_pushbuf_del(struct nouveau_pushbuf **ppush)
*ppush = NULL;
}
-struct nouveau_bufctx *
+drm_public struct nouveau_bufctx *
nouveau_pushbuf_bufctx(struct nouveau_pushbuf *push, struct nouveau_bufctx *ctx)
{
struct nouveau_bufctx *prev = push->bufctx;
@@ -637,7 +633,7 @@ nouveau_pushbuf_bufctx(struct nouveau_pushbuf *push, struct nouveau_bufctx *ctx)
return prev;
}
-int
+drm_public int
nouveau_pushbuf_space(struct nouveau_pushbuf *push,
uint32_t dwords, uint32_t relocs, uint32_t pushes)
{
@@ -701,7 +697,7 @@ nouveau_pushbuf_space(struct nouveau_pushbuf *push,
return flushed ? pushbuf_validate(push, false) : 0;
}
-void
+drm_public void
nouveau_pushbuf_data(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
uint64_t offset, uint64_t length)
{
@@ -732,14 +728,14 @@ nouveau_pushbuf_data(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
}
}
-int
+drm_public int
nouveau_pushbuf_refn(struct nouveau_pushbuf *push,
struct nouveau_pushbuf_refn *refs, int nr)
{
return pushbuf_refn(push, true, refs, nr);
}
-void
+drm_public void
nouveau_pushbuf_reloc(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
uint32_t data, uint32_t flags, uint32_t vor, uint32_t tor)
{
@@ -747,13 +743,13 @@ nouveau_pushbuf_reloc(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
push->cur++;
}
-int
+drm_public int
nouveau_pushbuf_validate(struct nouveau_pushbuf *push)
{
return pushbuf_validate(push, true);
}
-uint32_t
+drm_public uint32_t
nouveau_pushbuf_refd(struct nouveau_pushbuf *push, struct nouveau_bo *bo)
{
struct drm_nouveau_gem_pushbuf_bo *kref;
@@ -771,7 +767,7 @@ nouveau_pushbuf_refd(struct nouveau_pushbuf *push, struct nouveau_bo *bo)
return flags;
}
-int
+drm_public int
nouveau_pushbuf_kick(struct nouveau_pushbuf *push, struct nouveau_object *chan)
{
if (!push->channel)
diff --git a/omap/Android.bp b/omap/Android.bp
new file mode 100644
index 00000000..05ca7d2d
--- /dev/null
+++ b/omap/Android.bp
@@ -0,0 +1,12 @@
+build = ["Android.sources.bp"]
+
+cc_library_shared {
+ name: "libdrm_omap",
+ defaults: [
+ "libdrm_defaults",
+ "libdrm_omap_sources",
+ ],
+ vendor: true,
+
+ shared_libs: ["libdrm"],
+}
diff --git a/omap/Android.sources.bp b/omap/Android.sources.bp
new file mode 100644
index 00000000..3c7da94a
--- /dev/null
+++ b/omap/Android.sources.bp
@@ -0,0 +1,8 @@
+// Autogenerated with Android.sources.bp.mk
+
+cc_defaults {
+ name: "libdrm_omap_sources",
+ srcs: [
+ "omap_drm.c",
+ ],
+}
diff --git a/omap/Makefile.am b/omap/Makefile.am
index 599bb9de..38a1007b 100644
--- a/omap/Makefile.am
+++ b/omap/Makefile.am
@@ -1,5 +1,6 @@
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
@@ -20,5 +21,6 @@ libdrm_omapinclude_HEADERS = omap_drmif.h
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_omap.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = omap-symbol-check
EXTRA_DIST = $(TESTS)
diff --git a/omap/meson.build b/omap/meson.build
new file mode 100644
index 00000000..54698c6a
--- /dev/null
+++ b/omap/meson.build
@@ -0,0 +1,54 @@
+# 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.
+
+libdrm_omap = shared_library(
+ 'drm_omap',
+ [files('omap_drm.c'), config_file],
+ include_directories : [inc_root, inc_drm],
+ c_args : libdrm_c_args,
+ link_with : libdrm,
+ dependencies : [dep_pthread_stubs, dep_atomic_ops],
+ version : '1.0.0',
+ install : true,
+)
+
+ext_libdrm_omap = declare_dependency(
+ link_with : [libdrm, libdrm_omap],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+install_headers('omap_drmif.h', subdir : 'libdrm')
+install_headers('omap_drm.h', subdir : 'omap')
+
+pkg.generate(
+ name : 'libdrm_omap',
+ libraries : libdrm_omap,
+ subdirs : ['.', 'libdrm', 'omap'],
+ version : '0.6',
+ requires_private : 'libdrm',
+ description : 'Userspace interface to omap kernel DRM services',
+)
+
+test(
+ 'omap-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('omap-symbol-check'), libdrm_omap]
+)
diff --git a/omap/omap-symbol-check b/omap/omap-symbol-check
index 759c84bd..16da3c40 100755
--- a/omap/omap-symbol-check
+++ b/omap/omap-symbol-check
@@ -1,9 +1,11 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.am/libdrm_omap*HEADERS
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_omap.so} | awk '{print $3}'| while read func; do
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_omap.so} | awk '{print $3}'| while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
__bss_start
_edata
diff --git a/omap/omap_drm.c b/omap/omap_drm.c
index 08ba64eb..ffacea69 100644
--- a/omap/omap_drm.c
+++ b/omap/omap_drm.c
@@ -26,10 +26,6 @@
* Rob Clark <rob@ti.com>
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <linux/stddef.h>
#include <linux/types.h>
@@ -92,7 +88,7 @@ static struct omap_device * omap_device_new_impl(int fd)
return dev;
}
-struct omap_device * omap_device_new(int fd)
+drm_public struct omap_device * omap_device_new(int fd)
{
struct omap_device *dev = NULL;
@@ -115,13 +111,13 @@ struct omap_device * omap_device_new(int fd)
return dev;
}
-struct omap_device * omap_device_ref(struct omap_device *dev)
+drm_public struct omap_device * omap_device_ref(struct omap_device *dev)
{
atomic_inc(&dev->refcnt);
return dev;
}
-void omap_device_del(struct omap_device *dev)
+drm_public void omap_device_del(struct omap_device *dev)
{
if (!atomic_dec_and_test(&dev->refcnt))
return;
@@ -132,7 +128,7 @@ void omap_device_del(struct omap_device *dev)
free(dev);
}
-int
+drm_public int
omap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value)
{
struct drm_omap_param req = {
@@ -150,7 +146,7 @@ omap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value)
return 0;
}
-int
+drm_public int
omap_set_param(struct omap_device *dev, uint64_t param, uint64_t value)
{
struct drm_omap_param req = {
@@ -230,7 +226,7 @@ fail:
/* allocate a new (un-tiled) buffer object */
-struct omap_bo *
+drm_public struct omap_bo *
omap_bo_new(struct omap_device *dev, uint32_t size, uint32_t flags)
{
union omap_gem_size gsize = {
@@ -243,7 +239,7 @@ omap_bo_new(struct omap_device *dev, uint32_t size, uint32_t flags)
}
/* allocate a new buffer object */
-struct omap_bo *
+drm_public struct omap_bo *
omap_bo_new_tiled(struct omap_device *dev, uint32_t width,
uint32_t height, uint32_t flags)
{
@@ -259,7 +255,7 @@ omap_bo_new_tiled(struct omap_device *dev, uint32_t width,
return omap_bo_new_impl(dev, gsize, flags);
}
-struct omap_bo *omap_bo_ref(struct omap_bo *bo)
+drm_public struct omap_bo *omap_bo_ref(struct omap_bo *bo)
{
atomic_inc(&bo->refcnt);
return bo;
@@ -285,7 +281,7 @@ static int get_buffer_info(struct omap_bo *bo)
}
/* import a buffer object from DRI2 name */
-struct omap_bo *
+drm_public struct omap_bo *
omap_bo_from_name(struct omap_device *dev, uint32_t name)
{
struct omap_bo *bo = NULL;
@@ -319,7 +315,7 @@ fail:
* fd so caller should close() the fd when it is otherwise done
* with it (even if it is still using the 'struct omap_bo *')
*/
-struct omap_bo *
+drm_public struct omap_bo *
omap_bo_from_dmabuf(struct omap_device *dev, int fd)
{
struct omap_bo *bo = NULL;
@@ -351,7 +347,7 @@ fail:
}
/* destroy a buffer object */
-void omap_bo_del(struct omap_bo *bo)
+drm_public void omap_bo_del(struct omap_bo *bo)
{
if (!bo) {
return;
@@ -384,7 +380,7 @@ void omap_bo_del(struct omap_bo *bo)
}
/* get the global flink/DRI2 buffer name */
-int omap_bo_get_name(struct omap_bo *bo, uint32_t *name)
+drm_public int omap_bo_get_name(struct omap_bo *bo, uint32_t *name)
{
if (!bo->name) {
struct drm_gem_flink req = {
@@ -405,7 +401,7 @@ int omap_bo_get_name(struct omap_bo *bo, uint32_t *name)
return 0;
}
-uint32_t omap_bo_handle(struct omap_bo *bo)
+drm_public uint32_t omap_bo_handle(struct omap_bo *bo)
{
return bo->handle;
}
@@ -413,12 +409,12 @@ uint32_t omap_bo_handle(struct omap_bo *bo)
/* caller owns the dmabuf fd that is returned and is responsible
* to close() it when done
*/
-int omap_bo_dmabuf(struct omap_bo *bo)
+drm_public int omap_bo_dmabuf(struct omap_bo *bo)
{
if (bo->fd < 0) {
struct drm_prime_handle req = {
.handle = bo->handle,
- .flags = DRM_CLOEXEC,
+ .flags = DRM_CLOEXEC | DRM_RDWR,
};
int ret;
@@ -432,7 +428,7 @@ int omap_bo_dmabuf(struct omap_bo *bo)
return dup(bo->fd);
}
-uint32_t omap_bo_size(struct omap_bo *bo)
+drm_public uint32_t omap_bo_size(struct omap_bo *bo)
{
if (!bo->size) {
get_buffer_info(bo);
@@ -440,7 +436,7 @@ uint32_t omap_bo_size(struct omap_bo *bo)
return bo->size;
}
-void *omap_bo_map(struct omap_bo *bo)
+drm_public void *omap_bo_map(struct omap_bo *bo)
{
if (!bo->map) {
if (!bo->offset) {
@@ -456,7 +452,7 @@ void *omap_bo_map(struct omap_bo *bo)
return bo->map;
}
-int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op)
+drm_public int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op)
{
struct drm_omap_gem_cpu_prep req = {
.handle = bo->handle,
@@ -466,7 +462,7 @@ int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op)
DRM_OMAP_GEM_CPU_PREP, &req, sizeof(req));
}
-int omap_bo_cpu_fini(struct omap_bo *bo, enum omap_gem_op op)
+drm_public int omap_bo_cpu_fini(struct omap_bo *bo, enum omap_gem_op op)
{
struct drm_omap_gem_cpu_fini req = {
.handle = bo->handle,
diff --git a/radeon/Makefile.am b/radeon/Makefile.am
index e2415314..e712a4ac 100644
--- a/radeon/Makefile.am
+++ b/radeon/Makefile.am
@@ -26,6 +26,7 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
@@ -43,5 +44,6 @@ libdrm_radeoninclude_HEADERS = $(LIBDRM_RADEON_H_FILES)
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_radeon.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = radeon-symbol-check
EXTRA_DIST = $(LIBDRM_RADEON_BOF_FILES) $(TESTS)
diff --git a/radeon/meson.build b/radeon/meson.build
new file mode 100644
index 00000000..1fc5282c
--- /dev/null
+++ b/radeon/meson.build
@@ -0,0 +1,64 @@
+# 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.
+
+
+libdrm_radeon = shared_library(
+ 'drm_radeon',
+ [
+ files(
+ 'radeon_bo_gem.c', 'radeon_cs_gem.c', 'radeon_cs_space.c', 'radeon_bo.c',
+ 'radeon_cs.c', 'radeon_surface.c',
+ ),
+ config_file,
+ ],
+ c_args : libdrm_c_args,
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ dependencies : [dep_pthread_stubs, dep_atomic_ops],
+ version : '1.0.1',
+ install : true,
+)
+
+ext_libdrm_radeon = declare_dependency(
+ link_with : [libdrm, libdrm_radeon],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+install_headers(
+ 'radeon_bo.h', 'radeon_cs.h', 'radeon_surface.h', 'radeon_bo_gem.h',
+ 'radeon_cs_gem.h', 'radeon_bo_int.h', 'radeon_cs_int.h', 'r600_pci_ids.h',
+ subdir : 'libdrm'
+)
+
+pkg.generate(
+ name : 'libdrm_radeon',
+ libraries : libdrm_radeon,
+ subdirs : ['.', 'libdrm'],
+ version : meson.project_version(),
+ requires_private : 'libdrm',
+ description : 'Userspace interface to kernel DRM services for radeon',
+)
+
+test(
+ 'radeon-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('radeon-symbol-check'), libdrm_radeon]
+)
diff --git a/radeon/radeon-symbol-check b/radeon/radeon-symbol-check
index 0bf2ffcb..da605bb8 100755
--- a/radeon/radeon-symbol-check
+++ b/radeon/radeon-symbol-check
@@ -1,9 +1,11 @@
#!/bin/bash
+set -u
+
# The following symbols (past the first five) are taken from the public headers.
# A list of the latter should be available Makefile.sources/LIBDRM_RADEON_H_FILES
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_radeon.so} | awk '{print $3}'| while read func; do
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_radeon.so} | awk '{print $3}'| while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
__bss_start
_edata
diff --git a/radeon/radeon_bo.c b/radeon/radeon_bo.c
index 447f9280..91929532 100644
--- a/radeon/radeon_bo.c
+++ b/radeon/radeon_bo.c
@@ -29,14 +29,11 @@
* Dave Airlie
* Jérôme Glisse <glisse@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <libdrm_macros.h>
#include <radeon_bo.h>
#include <radeon_bo_int.h>
-void radeon_bo_debug(struct radeon_bo *bo, const char *op)
+drm_public void radeon_bo_debug(struct radeon_bo *bo, const char *op)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
@@ -44,7 +41,7 @@ void radeon_bo_debug(struct radeon_bo *bo, const char *op)
op, bo, bo->handle, boi->size, boi->cref);
}
-struct radeon_bo *
+drm_public struct radeon_bo *
radeon_bo_open(struct radeon_bo_manager *bom, uint32_t handle, uint32_t size,
uint32_t alignment, uint32_t domains, uint32_t flags)
{
@@ -53,14 +50,14 @@ radeon_bo_open(struct radeon_bo_manager *bom, uint32_t handle, uint32_t size,
return bo;
}
-void radeon_bo_ref(struct radeon_bo *bo)
+drm_public void radeon_bo_ref(struct radeon_bo *bo)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
boi->cref++;
boi->bom->funcs->bo_ref(boi);
}
-struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo)
+drm_public struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
if (bo == NULL)
@@ -70,19 +67,19 @@ struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo)
return boi->bom->funcs->bo_unref(boi);
}
-int radeon_bo_map(struct radeon_bo *bo, int write)
+drm_public int radeon_bo_map(struct radeon_bo *bo, int write)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
return boi->bom->funcs->bo_map(boi, write);
}
-int radeon_bo_unmap(struct radeon_bo *bo)
+drm_public int radeon_bo_unmap(struct radeon_bo *bo)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
return boi->bom->funcs->bo_unmap(boi);
}
-int radeon_bo_wait(struct radeon_bo *bo)
+drm_public int radeon_bo_wait(struct radeon_bo *bo)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
if (!boi->bom->funcs->bo_wait)
@@ -90,13 +87,13 @@ int radeon_bo_wait(struct radeon_bo *bo)
return boi->bom->funcs->bo_wait(boi);
}
-int radeon_bo_is_busy(struct radeon_bo *bo, uint32_t *domain)
+drm_public int radeon_bo_is_busy(struct radeon_bo *bo, uint32_t *domain)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
return boi->bom->funcs->bo_is_busy(boi, domain);
}
-int
+drm_public int
radeon_bo_set_tiling(struct radeon_bo *bo,
uint32_t tiling_flags, uint32_t pitch)
{
@@ -104,7 +101,7 @@ radeon_bo_set_tiling(struct radeon_bo *bo,
return boi->bom->funcs->bo_set_tiling(boi, tiling_flags, pitch);
}
-int
+drm_public int
radeon_bo_get_tiling(struct radeon_bo *bo,
uint32_t *tiling_flags, uint32_t *pitch)
{
@@ -112,7 +109,7 @@ radeon_bo_get_tiling(struct radeon_bo *bo,
return boi->bom->funcs->bo_get_tiling(boi, tiling_flags, pitch);
}
-int radeon_bo_is_static(struct radeon_bo *bo)
+drm_public int radeon_bo_is_static(struct radeon_bo *bo)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
if (boi->bom->funcs->bo_is_static)
@@ -120,19 +117,19 @@ int radeon_bo_is_static(struct radeon_bo *bo)
return 0;
}
-int
+drm_public int
radeon_bo_is_referenced_by_cs(struct radeon_bo *bo, struct radeon_cs *cs)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
return boi->cref > 1;
}
-uint32_t radeon_bo_get_handle(struct radeon_bo *bo)
+drm_public uint32_t radeon_bo_get_handle(struct radeon_bo *bo)
{
return bo->handle;
}
-uint32_t radeon_bo_get_src_domain(struct radeon_bo *bo)
+drm_public uint32_t radeon_bo_get_src_domain(struct radeon_bo *bo)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
uint32_t src_domain;
diff --git a/radeon/radeon_bo_gem.c b/radeon/radeon_bo_gem.c
index fbd453d9..86f7c007 100644
--- a/radeon/radeon_bo_gem.c
+++ b/radeon/radeon_bo_gem.c
@@ -29,9 +29,6 @@
* Dave Airlie
* Jérôme Glisse <glisse@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@@ -284,7 +281,7 @@ static const struct radeon_bo_funcs bo_gem_funcs = {
.bo_is_referenced_by_cs = NULL,
};
-struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
+drm_public struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
{
struct bo_manager_gem *bomg;
@@ -297,7 +294,7 @@ struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
return (struct radeon_bo_manager*)bomg;
}
-void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
+drm_public void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
{
struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
@@ -307,21 +304,21 @@ void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
free(bomg);
}
-uint32_t
+drm_public uint32_t
radeon_gem_name_bo(struct radeon_bo *bo)
{
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
return bo_gem->name;
}
-void *
+drm_public void *
radeon_gem_get_reloc_in_cs(struct radeon_bo *bo)
{
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
return &bo_gem->reloc_in_cs;
}
-int
+drm_public int
radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
{
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
@@ -343,7 +340,7 @@ radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
return 0;
}
-int
+drm_public int
radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
{
struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
@@ -361,7 +358,7 @@ radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t writ
return r;
}
-int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
+drm_public int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
{
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
int ret;
@@ -370,7 +367,7 @@ int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
return ret;
}
-struct radeon_bo *
+drm_public struct radeon_bo *
radeon_gem_bo_open_prime(struct radeon_bo_manager *bom, int fd_handle, uint32_t size)
{
struct radeon_bo_gem *bo;
diff --git a/radeon/radeon_cs.c b/radeon/radeon_cs.c
index dffb869f..1132d069 100644
--- a/radeon/radeon_cs.c
+++ b/radeon/radeon_cs.c
@@ -1,19 +1,16 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include "libdrm_macros.h"
#include <stdio.h>
#include "radeon_cs.h"
#include "radeon_cs_int.h"
-struct radeon_cs *
+drm_public struct radeon_cs *
radeon_cs_create(struct radeon_cs_manager *csm, uint32_t ndw)
{
struct radeon_cs_int *csi = csm->funcs->cs_create(csm, ndw);
return (struct radeon_cs *)csi;
}
-int
+drm_public int
radeon_cs_write_reloc(struct radeon_cs *cs, struct radeon_bo *bo,
uint32_t read_domain, uint32_t write_domain,
uint32_t flags)
@@ -27,7 +24,7 @@ radeon_cs_write_reloc(struct radeon_cs *cs, struct radeon_bo *bo,
flags);
}
-int
+drm_public int
radeon_cs_begin(struct radeon_cs *cs, uint32_t ndw,
const char *file, const char *func, int line)
{
@@ -35,7 +32,7 @@ radeon_cs_begin(struct radeon_cs *cs, uint32_t ndw,
return csi->csm->funcs->cs_begin(csi, ndw, file, func, line);
}
-int
+drm_public int
radeon_cs_end(struct radeon_cs *cs,
const char *file, const char *func, int line)
{
@@ -43,37 +40,37 @@ radeon_cs_end(struct radeon_cs *cs,
return csi->csm->funcs->cs_end(csi, file, func, line);
}
-int radeon_cs_emit(struct radeon_cs *cs)
+drm_public int radeon_cs_emit(struct radeon_cs *cs)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
return csi->csm->funcs->cs_emit(csi);
}
-int radeon_cs_destroy(struct radeon_cs *cs)
+drm_public int radeon_cs_destroy(struct radeon_cs *cs)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
return csi->csm->funcs->cs_destroy(csi);
}
-int radeon_cs_erase(struct radeon_cs *cs)
+drm_public int radeon_cs_erase(struct radeon_cs *cs)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
return csi->csm->funcs->cs_erase(csi);
}
-int radeon_cs_need_flush(struct radeon_cs *cs)
+drm_public int radeon_cs_need_flush(struct radeon_cs *cs)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
return csi->csm->funcs->cs_need_flush(csi);
}
-void radeon_cs_print(struct radeon_cs *cs, FILE *file)
+drm_public void radeon_cs_print(struct radeon_cs *cs, FILE *file)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
csi->csm->funcs->cs_print(csi, file);
}
-void
+drm_public void
radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
@@ -83,7 +80,7 @@ radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
csi->csm->gart_limit = limit;
}
-void radeon_cs_space_set_flush(struct radeon_cs *cs,
+drm_public void radeon_cs_space_set_flush(struct radeon_cs *cs,
void (*fn)(void *), void *data)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
@@ -91,7 +88,7 @@ void radeon_cs_space_set_flush(struct radeon_cs *cs,
csi->space_flush_data = data;
}
-uint32_t radeon_cs_get_id(struct radeon_cs *cs)
+drm_public uint32_t radeon_cs_get_id(struct radeon_cs *cs)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
return csi->id;
diff --git a/radeon/radeon_cs_gem.c b/radeon/radeon_cs_gem.c
index f3dccb6c..ef070c60 100644
--- a/radeon/radeon_cs_gem.c
+++ b/radeon/radeon_cs_gem.c
@@ -29,9 +29,6 @@
* Nicolai Haehnle <prefect_@gmx.net>
* Jérôme Glisse <glisse@freedesktop.org>
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
@@ -539,7 +536,7 @@ static int radeon_get_device_id(int fd, uint32_t *device_id)
return r;
}
-struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
+drm_public struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
{
struct radeon_cs_manager_gem *csm;
@@ -553,7 +550,7 @@ struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
return &csm->base;
}
-void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
+drm_public void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
{
free(csm);
}
diff --git a/radeon/radeon_cs_space.c b/radeon/radeon_cs_space.c
index 69287be5..039b0414 100644
--- a/radeon/radeon_cs_space.c
+++ b/radeon/radeon_cs_space.c
@@ -25,9 +25,6 @@
*/
/*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
@@ -165,7 +162,7 @@ static int radeon_cs_do_space_check(struct radeon_cs_int *cs, struct radeon_cs_s
return RADEON_CS_SPACE_OK;
}
-void
+drm_public void
radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo,
uint32_t read_domains, uint32_t write_domain)
{
@@ -209,7 +206,7 @@ again:
return 0;
}
-int
+drm_public int
radeon_cs_space_check_with_bo(struct radeon_cs *cs, struct radeon_bo *bo,
uint32_t read_domains, uint32_t write_domain)
{
@@ -230,13 +227,13 @@ radeon_cs_space_check_with_bo(struct radeon_cs *cs, struct radeon_bo *bo,
return ret;
}
-int radeon_cs_space_check(struct radeon_cs *cs)
+drm_public int radeon_cs_space_check(struct radeon_cs *cs)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
return radeon_cs_check_space_internal(csi, NULL);
}
-void radeon_cs_space_reset_bos(struct radeon_cs *cs)
+drm_public void radeon_cs_space_reset_bos(struct radeon_cs *cs)
{
struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
int i;
diff --git a/radeon/radeon_surface.c b/radeon/radeon_surface.c
index 965be24c..ea0a27a9 100644
--- a/radeon/radeon_surface.c
+++ b/radeon/radeon_surface.c
@@ -26,9 +26,6 @@
* Authors:
* Jérôme Glisse <jglisse@redhat.com>
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
@@ -2411,7 +2408,7 @@ static int cik_surface_best(struct radeon_surface_manager *surf_man,
/* ===========================================================================
* public API
*/
-struct radeon_surface_manager *
+drm_public struct radeon_surface_manager *
radeon_surface_manager_new(int fd)
{
struct radeon_surface_manager *surf_man;
@@ -2460,7 +2457,7 @@ out_err:
return NULL;
}
-void
+drm_public void
radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
{
free(surf_man);
@@ -2503,6 +2500,7 @@ static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
if (surf->npix_y > 1) {
return -EINVAL;
}
+ /* fallthrough */
case RADEON_SURF_TYPE_2D:
if (surf->npix_z > 1) {
return -EINVAL;
@@ -2533,7 +2531,7 @@ static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
return 0;
}
-int
+drm_public int
radeon_surface_init(struct radeon_surface_manager *surf_man,
struct radeon_surface *surf)
{
@@ -2550,7 +2548,7 @@ radeon_surface_init(struct radeon_surface_manager *surf_man,
return surf_man->surface_init(surf_man, surf);
}
-int
+drm_public int
radeon_surface_best(struct radeon_surface_manager *surf_man,
struct radeon_surface *surf)
{
diff --git a/rockchip/Android.bp b/rockchip/Android.bp
deleted file mode 100644
index daceacca..00000000
--- a/rockchip/Android.bp
+++ /dev/null
@@ -1,13 +0,0 @@
-cc_library_shared {
- name: "libdrm_rockchip",
- vendor: true,
- shared_libs: ["libdrm"],
-
- srcs: ["rockchip_drm.c"],
-
- cflags: [
- "-DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1",
- "-Wall",
- "-Werror",
- ],
-}
diff --git a/rockchip/Makefile.am b/rockchip/Makefile.am
deleted file mode 100644
index 2ebb82f1..00000000
--- a/rockchip/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -I$(top_srcdir) \
- -I$(top_srcdir)/rockchip \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_rockchip_la_LTLIBRARIES = libdrm_rockchip.la
-libdrm_rockchip_ladir = $(libdir)
-libdrm_rockchip_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libdrm_rockchip_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
-
-libdrm_rockchip_la_SOURCES = \
- rockchip_drm.c
-
-libdrm_rockchipincludedir = ${includedir}/libdrm
-libdrm_rockchipinclude_HEADERS = rockchip_drmif.h rockchip_drm.h
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_rockchip.pc
diff --git a/rockchip/libdrm_rockchip.pc.in b/rockchip/libdrm_rockchip.pc.in
deleted file mode 100644
index 13f22ac7..00000000
--- a/rockchip/libdrm_rockchip.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: libdrm_rockchip
-Description: Userspace interface to rockchip kernel DRM services
-Version: 0.1
-Libs: -L${libdir} -ldrm_rockchip
-Cflags: -I${includedir} -I${includedir}/libdrm
-Requires.private: libdrm
diff --git a/rockchip/rockchip_drm.c b/rockchip/rockchip_drm.c
deleted file mode 100644
index 44a78be8..00000000
--- a/rockchip/rockchip_drm.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) ROCKCHIP, Inc.
- * Author:yzq<yzq@rock-chips.com>
- *
- * based on exynos_drm.c
- *
- * 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.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <sys/mman.h>
-#include <linux/stddef.h>
-
-#include <xf86drm.h>
-
-#include "rockchip_drm.h"
-#include "rockchip_drmif.h"
-
-/*
- * Create rockchip drm device object.
- *
- * @fd: file descriptor to rockchip drm driver opened.
- *
- * if true, return the device object else NULL.
- */
-struct rockchip_device *rockchip_device_create(int fd)
-{
- struct rockchip_device *dev;
-
- dev = calloc(1, sizeof(*dev));
- if (!dev) {
- fprintf(stderr, "failed to create device[%s].\n",
- strerror(errno));
- return NULL;
- }
-
- dev->fd = fd;
-
- return dev;
-}
-
-/*
- * Destroy rockchip drm device object
- *
- * @dev: rockchip drm device object.
- */
-void rockchip_device_destroy(struct rockchip_device *dev)
-{
- free(dev);
-}
-
-/*
- * Create a rockchip buffer object to rockchip drm device.
- *
- * @dev: rockchip drm device object.
- * @size: user-desired size.
- * flags: user-desired memory type.
- * user can set one or more types among several types to memory
- * allocation and cache attribute types. and as default,
- * ROCKCHIP_BO_NONCONTIG and ROCKCHIP-BO_NONCACHABLE types would
- * be used.
- *
- * if true, return a rockchip buffer object else NULL.
- */
-struct rockchip_bo *rockchip_bo_create(struct rockchip_device *dev,
- size_t size, uint32_t flags)
-{
- struct rockchip_bo *bo;
- struct drm_rockchip_gem_create req = {
- .size = size,
- .flags = flags,
- };
-
- if (size == 0) {
- fprintf(stderr, "invalid size.\n");
- return NULL;
- }
-
- bo = calloc(1, sizeof(*bo));
- if (!bo) {
- fprintf(stderr, "failed to create bo[%s].\n",
- strerror(errno));
- goto fail;
- }
-
- bo->dev = dev;
-
- if (drmIoctl(dev->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &req)){
- fprintf(stderr, "failed to create gem object[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
-
- bo->handle = req.handle;
- bo->size = size;
- bo->flags = flags;
-
- return bo;
-
-err_free_bo:
- free(bo);
-fail:
- return NULL;
-}
-
-struct rockchip_bo *rockchip_bo_from_handle(struct rockchip_device *dev,
- uint32_t handle, uint32_t flags, uint32_t size)
-{
- struct rockchip_bo *bo;
-
- if (size == 0) {
- fprintf(stderr, "invalid size.\n");
- return NULL;
- }
-
- bo = calloc(1, sizeof(*bo));
- if (!bo) {
- fprintf(stderr, "failed to create bo[%s].\n",
- strerror(errno));
- return NULL;
- }
-
- bo->dev = dev;
- bo->handle = handle;
- bo->size = size;
- bo->flags = flags;
-
- return bo;
-}
-
-/*
- * Destroy a rockchip buffer object.
- *
- * @bo: a rockchip buffer object to be destroyed.
- */
-void rockchip_bo_destroy(struct rockchip_bo *bo)
-{
- if (!bo)
- return;
-
- if (bo->vaddr)
- munmap(bo->vaddr, bo->size);
-
- if (bo->handle) {
- struct drm_gem_close req = {
- .handle = bo->handle,
- };
-
- drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
- }
-
- free(bo);
-}
-
-
-/*
- * Get a rockchip buffer object from a gem global object name.
- *
- * @dev: a rockchip device object.
- * @name: a gem global object name exported by another process.
- *
- * this interface is used to get a rockchip buffer object from a gem
- * global object name sent by another process for buffer sharing.
- *
- * if true, return a rockchip buffer object else NULL.
- *
- */
-struct rockchip_bo *rockchip_bo_from_name(struct rockchip_device *dev,
- uint32_t name)
-{
- struct rockchip_bo *bo;
- struct drm_gem_open req = {
- .name = name,
- };
-
- bo = calloc(1, sizeof(*bo));
- if (!bo) {
- fprintf(stderr, "failed to allocate bo[%s].\n",
- strerror(errno));
- return NULL;
- }
-
- if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
- fprintf(stderr, "failed to open gem object[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
-
- bo->dev = dev;
- bo->name = name;
- bo->handle = req.handle;
-
- return bo;
-
-err_free_bo:
- free(bo);
- return NULL;
-}
-
-/*
- * Get a gem global object name from a gem object handle.
- *
- * @bo: a rockchip buffer object including gem handle.
- * @name: a gem global object name to be got by kernel driver.
- *
- * this interface is used to get a gem global object name from a gem object
- * handle to a buffer that wants to share it with another process.
- *
- * if true, return 0 else negative.
- */
-int rockchip_bo_get_name(struct rockchip_bo *bo, uint32_t *name)
-{
- if (!bo->name) {
- struct drm_gem_flink req = {
- .handle = bo->handle,
- };
- int ret;
-
- ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
- if (ret) {
- fprintf(stderr, "failed to get gem global name[%s].\n",
- strerror(errno));
- return ret;
- }
-
- bo->name = req.name;
- }
-
- *name = bo->name;
-
- return 0;
-}
-
-uint32_t rockchip_bo_handle(struct rockchip_bo *bo)
-{
- return bo->handle;
-}
-
-/*
- * Mmap a buffer to user space.
- *
- * @bo: a rockchip buffer object including a gem object handle to be mmapped
- * to user space.
- *
- * if true, user pointer mmaped else NULL.
- */
-void *rockchip_bo_map(struct rockchip_bo *bo)
-{
- if (!bo->vaddr) {
- struct rockchip_device *dev = bo->dev;
- struct drm_rockchip_gem_map_off req = {
- .handle = bo->handle,
- };
- int ret;
-
- ret = drmIoctl(dev->fd, DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET, &req);
- if (ret) {
- fprintf(stderr, "failed to ioctl gem map offset[%s].\n",
- strerror(errno));
- return NULL;
- }
-
- bo->vaddr = mmap(0, bo->size, PROT_READ | PROT_WRITE,
- MAP_SHARED, dev->fd, req.offset);
- if (bo->vaddr == MAP_FAILED) {
- fprintf(stderr, "failed to mmap buffer[%s].\n",
- strerror(errno));
- return NULL;
- }
- }
-
- return bo->vaddr;
-}
diff --git a/rockchip/rockchip_drm.h b/rockchip/rockchip_drm.h
deleted file mode 100644
index 13977d59..00000000
--- a/rockchip/rockchip_drm.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) Fuzhou Rockchip Electronics Co.Ltd
- * Authors:
- * Mark Yao <yzq@rock-chips.com>
- *
- * based on exynos_drm.h
- *
- * 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 _ROCKCHIP_DRM_H_
-#define _ROCKCHIP_DRM_H_
-
-#include <stdint.h>
-#include "drm.h"
-
-/**
- * User-desired buffer creation information structure.
- *
- * @size: user-desired memory allocation size.
- * - this size value would be page-aligned internally.
- * @flags: user request for setting memory type or cache attributes.
- * @handle: returned a handle to created gem object.
- * - this handle will be set by gem module of kernel side.
- */
-struct drm_rockchip_gem_create {
- uint64_t size;
- uint32_t flags;
- uint32_t handle;
-};
-
-/**
- * A structure for getting buffer offset.
- *
- * @handle: a pointer to gem object created.
- * @pad: just padding to be 64-bit aligned.
- * @offset: relatived offset value of the memory region allocated.
- * - this value should be set by user.
- */
-struct drm_rockchip_gem_map_off {
- uint32_t handle;
- uint32_t pad;
- uint64_t offset;
-};
-
-#define DRM_ROCKCHIP_GEM_CREATE 0x00
-#define DRM_ROCKCHIP_GEM_MAP_OFFSET 0x01
-
-#define DRM_IOCTL_ROCKCHIP_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_ROCKCHIP_GEM_CREATE, struct drm_rockchip_gem_create)
-
-#define DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_ROCKCHIP_GEM_MAP_OFFSET, struct drm_rockchip_gem_map_off)
-
-#endif
diff --git a/rockchip/rockchip_drmif.h b/rockchip/rockchip_drmif.h
deleted file mode 100644
index 5c549a05..00000000
--- a/rockchip/rockchip_drmif.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) ROCKCHIP, Inc.
- * Author:yzq<yzq@rock-chips.com>
- *
- * based on exynos_drmif.h
- *
- * 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 ROCKCHIP_DRMIF_H_
-#define ROCKCHIP_DRMIF_H_
-
-#include <xf86drm.h>
-#include <stdint.h>
-#include "rockchip_drm.h"
-
-struct rockchip_device {
- int fd;
-};
-
-/*
- * Rockchip Buffer Object structure.
- *
- * @dev: rockchip device object allocated.
- * @handle: a gem handle to gem object created.
- * @flags: indicate memory allocation and cache attribute types.
- * @size: size to the buffer created.
- * @vaddr: user space address to a gem buffer mmaped.
- * @name: a gem global handle from flink request.
- */
-struct rockchip_bo {
- struct rockchip_device *dev;
- uint32_t handle;
- uint32_t flags;
- size_t size;
- void *vaddr;
- uint32_t name;
-};
-
-/*
- * device related functions:
- */
-struct rockchip_device *rockchip_device_create(int fd);
-void rockchip_device_destroy(struct rockchip_device *dev);
-
-/*
- * buffer-object related functions:
- */
-struct rockchip_bo *rockchip_bo_create(struct rockchip_device *dev,
- size_t size, uint32_t flags);
-int rockchip_bo_get_info(struct rockchip_device *dev, uint32_t handle,
- size_t *size, uint32_t *flags);
-void rockchip_bo_destroy(struct rockchip_bo *bo);
-struct rockchip_bo *rockchip_bo_from_name(struct rockchip_device *dev,
- uint32_t name);
-int rockchip_bo_get_name(struct rockchip_bo *bo, uint32_t *name);
-uint32_t rockchip_bo_handle(struct rockchip_bo *bo);
-struct rockchip_bo *rockchip_bo_from_handle(struct rockchip_device *dev,
- uint32_t handle, uint32_t flags, uint32_t size);
-void *rockchip_bo_map(struct rockchip_bo *bo);
-#endif /* ROCKCHIP_DRMIF_H_ */
diff --git a/tegra/Makefile.am b/tegra/Makefile.am
index fb40be55..53119970 100644
--- a/tegra/Makefile.am
+++ b/tegra/Makefile.am
@@ -4,7 +4,8 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
@PTHREADSTUBS_CFLAGS@ \
- $(WARN_CFLAGS)
+ $(WARN_CFLAGS) \
+ -fvisibility=hidden
libdrm_tegra_ladir = $(libdir)
libdrm_tegra_la_LTLIBRARIES = libdrm_tegra.la
@@ -21,5 +22,6 @@ libdrm_tegrainclude_HEADERS = tegra.h
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_tegra.pc
+AM_TESTS_ENVIRONMENT = NM='$(NM)'
TESTS = tegra-symbol-check
EXTRA_DIST = $(TESTS)
diff --git a/tegra/meson.build b/tegra/meson.build
new file mode 100644
index 00000000..4bc454b6
--- /dev/null
+++ b/tegra/meson.build
@@ -0,0 +1,53 @@
+# 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.
+
+libdrm_tegra = shared_library(
+ 'drm_tegra',
+ [files('tegra.c'), config_file],
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ dependencies : [dep_pthread_stubs, dep_atomic_ops],
+ c_args : libdrm_c_args,
+ version : '0.0.0',
+ install : true,
+)
+
+ext_libdrm_tegra = declare_dependency(
+ link_with : [libdrm, libdrm_tegra],
+ include_directories : [inc_drm, include_directories('.')],
+)
+
+install_headers('tegra.h', subdir : 'libdrm')
+
+pkg.generate(
+ name : 'libdrm_tegra',
+ libraries : libdrm_tegra,
+ subdirs : ['.', 'libdrm'],
+ version : meson.project_version(),
+ requires_private : 'libdrm',
+ description : 'Userspace interface to Tegra kernel DRM services',
+)
+
+test(
+ 'tegra-symbol-check',
+ prog_bash,
+ env : env_test,
+ args : [files('tegra-symbol-check'), libdrm_tegra]
+)
diff --git a/tegra/private.h b/tegra/private.h
index 571caa56..bb6c1a51 100644
--- a/tegra/private.h
+++ b/tegra/private.h
@@ -41,10 +41,9 @@ struct drm_tegra {
struct drm_tegra_bo {
struct drm_tegra *drm;
uint32_t handle;
- uint64_t offset;
+ uint32_t offset;
uint32_t flags;
uint32_t size;
- uint32_t name;
atomic_t ref;
void *map;
};
diff --git a/tegra/tegra-symbol-check b/tegra/tegra-symbol-check
index 40208311..8539b95b 100755
--- a/tegra/tegra-symbol-check
+++ b/tegra/tegra-symbol-check
@@ -1,11 +1,16 @@
#!/bin/bash
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.sources/LIBDRM_FREEDRENO_H_FILES
+set -u
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_tegra.so} | awk '{print $3}'| while read func; do
+# The following symbols (past the first nine) are taken from tegra.h.
+
+FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_tegra.so} | awk '{print $3}'| while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
+__bss_end__
+__bss_start__
__bss_start
+__end__
+_bss_end__
_edata
_end
_fini
diff --git a/tegra/tegra.c b/tegra/tegra.c
index 66f19e96..cf00a3ca 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -22,10 +22,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
#include <errno.h>
#include <fcntl.h>
#include <string.h>
@@ -74,7 +70,7 @@ static int drm_tegra_wrap(struct drm_tegra **drmp, int fd, bool close)
return 0;
}
-int drm_tegra_new(struct drm_tegra **drmp, int fd)
+drm_public int drm_tegra_new(struct drm_tegra **drmp, int fd)
{
bool supported = false;
drmVersionPtr version;
@@ -94,7 +90,7 @@ int drm_tegra_new(struct drm_tegra **drmp, int fd)
return drm_tegra_wrap(drmp, fd, false);
}
-void drm_tegra_close(struct drm_tegra *drm)
+drm_public void drm_tegra_close(struct drm_tegra *drm)
{
if (!drm)
return;
@@ -105,7 +101,7 @@ void drm_tegra_close(struct drm_tegra *drm)
free(drm);
}
-int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
+drm_public int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
uint32_t flags, uint32_t size)
{
struct drm_tegra_gem_create args;
@@ -143,7 +139,7 @@ int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
return 0;
}
-int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
+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)
{
struct drm_tegra_bo *bo;
@@ -166,62 +162,7 @@ int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
return 0;
}
-int drm_tegra_bo_name_ref(struct drm_tegra *drm, uint32_t name, uint32_t size,
- struct drm_tegra_bo **bop)
-{
- struct drm_tegra_bo *bo;
- struct drm_gem_open open_args;
- struct drm_gem_close close_args;
- int ret;
-
- memset(&open_args, 0, sizeof(open_args));
-
- open_args.name = name;
-
- ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, &open_args);
- if (ret)
- return ret;
-
- ret = drm_tegra_bo_wrap(bop, drm, open_args.handle, 0, size);
- if (ret)
- goto err;
-
- (*bop)->name = name;
-
- return 0;
-
-err:
- memset(&close_args, 0, sizeof(close_args));
- close_args.handle = open_args.handle;
- drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &close_args);
-
- return ret;
-}
-
-int drm_tegra_bo_name_get(struct drm_tegra_bo *bo, uint32_t *name)
-{
- struct drm_gem_flink args;
- int ret;
-
- args.handle = bo->handle;
-
- *name = bo->name;
- if (*name && *name != ~0U)
- return 0;
-
- ret = drmIoctl(bo->drm->fd, DRM_IOCTL_GEM_FLINK, &args);
- if (ret) {
- *name = 0;
- return ret;
- }
-
- bo->name = args.name;
- *name = bo->name;
-
- return 0;
-}
-
-struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo)
+drm_public struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo)
{
if (bo)
atomic_inc(&bo->ref);
@@ -229,13 +170,13 @@ struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo)
return bo;
}
-void drm_tegra_bo_unref(struct drm_tegra_bo *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);
}
-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;
@@ -245,7 +186,7 @@ int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle)
return 0;
}
-int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr)
+drm_public int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr)
{
struct drm_tegra *drm = bo->drm;
@@ -277,7 +218,7 @@ int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr)
return 0;
}
-int drm_tegra_bo_unmap(struct drm_tegra_bo *bo)
+drm_public int drm_tegra_bo_unmap(struct drm_tegra_bo *bo)
{
if (!bo)
return -EINVAL;
@@ -293,7 +234,7 @@ int drm_tegra_bo_unmap(struct drm_tegra_bo *bo)
return 0;
}
-int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags)
+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;
@@ -316,7 +257,7 @@ int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags)
return 0;
}
-int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags)
+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;
@@ -337,7 +278,7 @@ int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags)
return 0;
}
-int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo,
+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;
@@ -363,7 +304,7 @@ int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo,
return 0;
}
-int drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo,
+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;
diff --git a/tegra/tegra.h b/tegra/tegra.h
index e10eab71..31b0995a 100644
--- a/tegra/tegra.h
+++ b/tegra/tegra.h
@@ -38,11 +38,6 @@ 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_name_ref(struct drm_tegra *drm, uint32_t name, uint32_t size,
- struct drm_tegra_bo **bop);
-int drm_tegra_bo_name_get(struct drm_tegra_bo *bo, uint32_t *name);
-
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);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f2bb4d44..d274a3e9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,7 +1,7 @@
SUBDIRS = util kms modeprint proptest modetest vbltest
if HAVE_LIBKMS
-SUBDIRS += kmstest planetest
+SUBDIRS += kmstest
endif
if HAVE_RADEON
@@ -32,6 +32,7 @@ endif
AM_CFLAGS = \
$(WARN_CFLAGS)\
+ -fvisibility=hidden \
-I $(top_srcdir)/include/drm \
-I $(top_srcdir)
@@ -43,5 +44,10 @@ TESTS = \
random
check_PROGRAMS = \
- $(TESTS) \
- drmdevice
+ $(TESTS)
+
+if HAVE_INSTALL_TESTS
+bin_PROGRAMS = drmdevice
+else
+check_PROGRAMS += drmdevice
+endif
diff --git a/tests/amdgpu/.editorconfig b/tests/amdgpu/.editorconfig
new file mode 120000
index 00000000..70734e42
--- /dev/null
+++ b/tests/amdgpu/.editorconfig
@@ -0,0 +1 @@
+../../amdgpu/.editorconfig \ No newline at end of file
diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
index c1c3a32e..447ff217 100644
--- a/tests/amdgpu/Makefile.am
+++ b/tests/amdgpu/Makefile.am
@@ -1,7 +1,9 @@
AM_CFLAGS = \
+ -fvisibility=hidden \
-I $(top_srcdir)/include/drm \
-I $(top_srcdir)/amdgpu \
- -I $(top_srcdir)
+ -I $(top_srcdir) \
+ -pthread
LDADD = $(top_builddir)/libdrm.la \
$(top_builddir)/amdgpu/libdrm_amdgpu.la \
@@ -23,7 +25,12 @@ amdgpu_test_SOURCES = \
basic_tests.c \
bo_tests.c \
cs_tests.c \
- uvd_messages.h \
+ decode_messages.h \
vce_tests.c \
vce_ib.h \
- frame.h
+ frame.h \
+ uvd_enc_tests.c \
+ vcn_tests.c \
+ uve_ib.h \
+ deadlock_tests.c \
+ vm_tests.c
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index 3fd6820a..ebf44098 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/tests/amdgpu/amdgpu_test.c
@@ -21,10 +21,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -49,6 +45,17 @@
#include "CUnit/Basic.h"
#include "amdgpu_test.h"
+#include "amdgpu_internal.h"
+
+/* Test suite names */
+#define BASIC_TESTS_STR "Basic Tests"
+#define BO_TESTS_STR "BO Tests"
+#define CS_TESTS_STR "CS Tests"
+#define VCE_TESTS_STR "VCE Tests"
+#define VCN_TESTS_STR "VCN Tests"
+#define UVD_ENC_TESTS_STR "UVD ENC Tests"
+#define DEADLOCK_TESTS_STR "Deadlock Tests"
+#define VM_TESTS_STR "VM Tests"
/**
* Open handles for amdgpu devices
@@ -62,49 +69,150 @@ int open_render_node = 0; /* By default run most tests on primary node */
/** The table of all known test suites to run */
static CU_SuiteInfo suites[] = {
{
- .pName = "Basic Tests",
+ .pName = BASIC_TESTS_STR,
.pInitFunc = suite_basic_tests_init,
.pCleanupFunc = suite_basic_tests_clean,
.pTests = basic_tests,
},
{
- .pName = "BO Tests",
+ .pName = BO_TESTS_STR,
.pInitFunc = suite_bo_tests_init,
.pCleanupFunc = suite_bo_tests_clean,
.pTests = bo_tests,
},
{
- .pName = "CS Tests",
+ .pName = CS_TESTS_STR,
.pInitFunc = suite_cs_tests_init,
.pCleanupFunc = suite_cs_tests_clean,
.pTests = cs_tests,
},
{
- .pName = "VCE Tests",
+ .pName = VCE_TESTS_STR,
.pInitFunc = suite_vce_tests_init,
.pCleanupFunc = suite_vce_tests_clean,
.pTests = vce_tests,
},
+ {
+ .pName = VCN_TESTS_STR,
+ .pInitFunc = suite_vcn_tests_init,
+ .pCleanupFunc = suite_vcn_tests_clean,
+ .pTests = vcn_tests,
+ },
+ {
+ .pName = UVD_ENC_TESTS_STR,
+ .pInitFunc = suite_uvd_enc_tests_init,
+ .pCleanupFunc = suite_uvd_enc_tests_clean,
+ .pTests = uvd_enc_tests,
+ },
+ {
+ .pName = DEADLOCK_TESTS_STR,
+ .pInitFunc = suite_deadlock_tests_init,
+ .pCleanupFunc = suite_deadlock_tests_clean,
+ .pTests = deadlock_tests,
+ },
+ {
+ .pName = VM_TESTS_STR,
+ .pInitFunc = suite_vm_tests_init,
+ .pCleanupFunc = suite_vm_tests_clean,
+ .pTests = vm_tests,
+ },
+
CU_SUITE_INFO_NULL,
};
+typedef CU_BOOL (*active__stat_func)(void);
-/** Display information about all suites and their tests */
+typedef struct Suites_Active_Status {
+ char* pName;
+ active__stat_func pActive;
+}Suites_Active_Status;
+
+static CU_BOOL always_active()
+{
+ return CU_TRUE;
+}
+
+static Suites_Active_Status suites_active_stat[] = {
+ {
+ .pName = BASIC_TESTS_STR,
+ .pActive = always_active,
+ },
+ {
+ .pName = BO_TESTS_STR,
+ .pActive = always_active,
+ },
+ {
+ .pName = CS_TESTS_STR,
+ .pActive = suite_cs_tests_enable,
+ },
+ {
+ .pName = VCE_TESTS_STR,
+ .pActive = suite_vce_tests_enable,
+ },
+ {
+ .pName = VCN_TESTS_STR,
+ .pActive = suite_vcn_tests_enable,
+ },
+ {
+ .pName = UVD_ENC_TESTS_STR,
+ .pActive = suite_uvd_enc_tests_enable,
+ },
+ {
+ .pName = DEADLOCK_TESTS_STR,
+ .pActive = suite_deadlock_tests_enable,
+ },
+ {
+ .pName = VM_TESTS_STR,
+ .pActive = suite_vm_tests_enable,
+ },
+};
+
+
+/*
+ * Display information about all suites and their tests
+ *
+ * NOTE: Must be run after registry is initialized and suites registered.
+ */
static void display_test_suites(void)
{
int iSuite;
int iTest;
+ CU_pSuite pSuite = NULL;
+ CU_pTest pTest = NULL;
printf("Suites\n");
for (iSuite = 0; suites[iSuite].pName != NULL; iSuite++) {
- printf("Suite id = %d: Name '%s'\n",
- iSuite + 1, suites[iSuite].pName);
+
+ pSuite = CU_get_suite_by_index((unsigned int) iSuite + 1,
+ CU_get_registry());
+
+ if (!pSuite) {
+ fprintf(stderr, "Invalid suite id : %d\n", iSuite + 1);
+ continue;
+ }
+
+ printf("Suite id = %d: Name '%s status: %s'\n",
+ iSuite + 1, suites[iSuite].pName,
+ pSuite->fActive ? "ENABLED" : "DISABLED");
+
+
for (iTest = 0; suites[iSuite].pTests[iTest].pName != NULL;
iTest++) {
- printf(" Test id %d: Name: '%s'\n", iTest + 1,
- suites[iSuite].pTests[iTest].pName);
+
+ pTest = CU_get_test_by_index((unsigned int) iTest + 1,
+ pSuite);
+
+ if (!pTest) {
+ fprintf(stderr, "Invalid test id : %d\n", iTest + 1);
+ continue;
+ }
+
+ printf("Test id %d: Name: '%s status: %s'\n", iTest + 1,
+ suites[iSuite].pTests[iTest].pName,
+ pSuite->fActive && pTest->fActive ?
+ "ENABLED" : "DISABLED");
}
}
}
@@ -112,7 +220,7 @@ static void display_test_suites(void)
/** Help string for command line parameters */
static const char usage[] =
- "Usage: %s [-hlpr] [<-s <suite id>> [-t <test id>]] "
+ "Usage: %s [-hlpr] [<-s <suite id>> [-t <test id>] [-f]] "
"[-b <pci_bus_id> [-d <pci_device_id>]]\n"
"where:\n"
" l - Display all suites and their tests\n"
@@ -120,9 +228,10 @@ static const char usage[] =
" b - Specify device's PCI bus id to run tests\n"
" d - Specify device's PCI device id to run tests (optional)\n"
" p - Display information of AMDGPU devices in system\n"
+ " f - Force executing inactive suite or test\n"
" h - Display this help\n";
/** Specified options strings for getopt */
-static const char options[] = "hlrps:t:b:d:";
+static const char options[] = "hlrps:t:b:d:f";
/* Open AMD devices.
* Return the number of AMD device openned.
@@ -130,7 +239,6 @@ static const char options[] = "hlrps:t:b:d:";
static int amdgpu_open_devices(int open_render_node)
{
drmDevicePtr devices[MAX_CARDS_SUPPORTED];
- int ret;
int i;
int drm_node;
int amd_index = 0;
@@ -264,29 +372,72 @@ static void amdgpu_print_devices()
/* Find a match AMD device in PCI bus
* Return the index of the device or -1 if not found
*/
-static int amdgpu_find_device(uint8_t bus, uint8_t dev)
+static int amdgpu_find_device(uint8_t bus, uint16_t dev)
{
int i;
drmDevicePtr device;
- for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >=0; i++)
+ for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
if (drmGetDevice2(drm_amdgpu[i],
DRM_DEVICE_GET_PCI_REVISION,
&device) == 0) {
if (device->bustype == DRM_BUS_PCI)
- if (device->businfo.pci->bus == bus &&
- device->businfo.pci->dev == dev) {
-
+ if ((bus == 0xFF || device->businfo.pci->bus == bus) &&
+ device->deviceinfo.pci->device_id == dev) {
drmFreeDevice(&device);
return i;
}
drmFreeDevice(&device);
}
+ }
return -1;
}
+static void amdgpu_disable_suites()
+{
+ amdgpu_device_handle device_handle;
+ uint32_t major_version, minor_version, family_id;
+ int i;
+ int size = sizeof(suites_active_stat) / sizeof(suites_active_stat[0]);
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return;
+
+ family_id = device_handle->info.family_id;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return;
+
+ /* Set active status for suites based on their policies */
+ for (i = 0; i < size; ++i)
+ if (amdgpu_set_suite_active(suites_active_stat[i].pName,
+ suites_active_stat[i].pActive()))
+ fprintf(stderr, "suite deactivation failed - %s\n", CU_get_error_msg());
+
+ /* Explicitly disable specific tests due to known bugs or preferences */
+ /*
+ * BUG: Compute ring stalls and never recovers when the address is
+ * written after the command already submitted
+ */
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "compute ring block test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ if (amdgpu_set_test_active(BO_TESTS_STR, "Metadata", 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());
+
+ /* This test was ran on GFX8 and GFX9 only */
+ if (family_id < AMDGPU_FAMILY_VI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Sync dependency Test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+}
+
/* The main() function for setting up and running the tests.
* Returns a CUE_SUCCESS on successful running, another
* CUnit error code on failure.
@@ -303,6 +454,8 @@ int main(int argc, char **argv)
CU_pSuite pSuite = NULL;
CU_pTest pTest = NULL;
int test_device_index;
+ int display_list = 0;
+ int force_run = 0;
for (i = 0; i < MAX_CARDS_SUPPORTED; i++)
drm_amdgpu[i] = -1;
@@ -313,8 +466,8 @@ int main(int argc, char **argv)
while ((c = getopt(argc, argv, options)) != -1) {
switch (c) {
case 'l':
- display_test_suites();
- exit(EXIT_SUCCESS);
+ display_list = 1;
+ break;
case 's':
suite_id = atoi(optarg);
break;
@@ -325,7 +478,7 @@ int main(int argc, char **argv)
pci_bus_id = atoi(optarg);
break;
case 'd':
- pci_device_id = atoi(optarg);
+ sscanf(optarg, "%x", &pci_device_id);
break;
case 'p':
display_devices = 1;
@@ -333,6 +486,9 @@ int main(int argc, char **argv)
case 'r':
open_render_node = 1;
break;
+ case 'f':
+ force_run = 1;
+ break;
case '?':
case 'h':
fprintf(stderr, usage, argv[0]);
@@ -359,10 +515,10 @@ int main(int argc, char **argv)
exit(EXIT_SUCCESS);
}
- if (pci_bus_id > 0) {
+ if (pci_bus_id > 0 || pci_device_id) {
/* A device was specified to run the test */
- test_device_index = amdgpu_find_device((uint8_t)pci_bus_id,
- (uint8_t)pci_device_id);
+ test_device_index = amdgpu_find_device(pci_bus_id,
+ pci_device_id);
if (test_device_index >= 0) {
/* Most tests run on device of drm_amdgpu[0].
@@ -398,17 +554,33 @@ int main(int argc, char **argv)
/* Run tests using the CUnit Basic interface */
CU_basic_set_mode(CU_BRM_VERBOSE);
+ /* Disable suites and individual tests based on misc. conditions */
+ amdgpu_disable_suites();
+
+ if (display_list) {
+ display_test_suites();
+ goto end;
+ }
+
if (suite_id != -1) { /* If user specify particular suite? */
pSuite = CU_get_suite_by_index((unsigned int) suite_id,
CU_get_registry());
if (pSuite) {
+
+ if (force_run)
+ CU_set_suite_active(pSuite, CU_TRUE);
+
if (test_id != -1) { /* If user specify test id */
pTest = CU_get_test_by_index(
(unsigned int) test_id,
pSuite);
- if (pTest)
+ if (pTest) {
+ if (force_run)
+ CU_set_test_active(pTest, CU_TRUE);
+
CU_basic_run_test(pSuite, pTest);
+ }
else {
fprintf(stderr, "Invalid test id: %d\n",
test_id);
@@ -428,6 +600,7 @@ int main(int argc, char **argv)
} else
CU_basic_run_tests();
+end:
CU_cleanup_registry();
amdgpu_close_devices();
return CU_get_error();
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
index e30e2312..af81eea8 100644
--- a/tests/amdgpu/amdgpu_test.h
+++ b/tests/amdgpu/amdgpu_test.h
@@ -30,7 +30,7 @@
/**
* Define max. number of card in system which we are able to handle
*/
-#define MAX_CARDS_SUPPORTED 4
+#define MAX_CARDS_SUPPORTED 128
/* Forward reference for array to keep "drm" handles */
extern int drm_amdgpu[MAX_CARDS_SUPPORTED];
@@ -85,6 +85,11 @@ int suite_cs_tests_init();
int suite_cs_tests_clean();
/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_cs_tests_enable(void);
+
+/**
* Tests in cs test suite
*/
extern CU_TestInfo cs_tests[];
@@ -100,11 +105,96 @@ int suite_vce_tests_init();
int suite_vce_tests_clean();
/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_vce_tests_enable(void);
+
+/**
* Tests in vce test suite
*/
extern CU_TestInfo vce_tests[];
/**
++ * Initialize vcn test suite
++ */
+int suite_vcn_tests_init();
+
+/**
++ * Deinitialize vcn test suite
++ */
+int suite_vcn_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_vcn_tests_enable(void);
+
+/**
++ * Tests in vcn test suite
++ */
+extern CU_TestInfo vcn_tests[];
+
+/**
+ * Initialize uvd enc test suite
+ */
+int suite_uvd_enc_tests_init();
+
+/**
+ * Deinitialize uvd enc test suite
+ */
+int suite_uvd_enc_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_uvd_enc_tests_enable(void);
+
+/**
+ * Tests in uvd enc test suite
+ */
+extern CU_TestInfo uvd_enc_tests[];
+
+/**
+ * Initialize deadlock test suite
+ */
+int suite_deadlock_tests_init();
+
+/**
+ * Deinitialize deadlock test suite
+ */
+int suite_deadlock_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_deadlock_tests_enable(void);
+
+/**
+ * Tests in uvd enc test suite
+ */
+extern CU_TestInfo deadlock_tests[];
+
+/**
+ * Initialize vm test suite
+ */
+int suite_vm_tests_init();
+
+/**
+ * Deinitialize deadlock test suite
+ */
+int suite_vm_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_vm_tests_enable(void);
+
+/**
+ * Tests in vm test suite
+ */
+extern CU_TestInfo vm_tests[];
+
+/**
* Helper functions
*/
static inline amdgpu_bo_handle gpu_mem_alloc(
@@ -117,11 +207,9 @@ static inline amdgpu_bo_handle gpu_mem_alloc(
amdgpu_va_handle *va_handle)
{
struct amdgpu_bo_alloc_request req = {0};
- amdgpu_bo_handle buf_handle;
+ amdgpu_bo_handle buf_handle = NULL;
int r;
- CU_ASSERT_NOT_EQUAL(vmc_addr, NULL);
-
req.alloc_size = size;
req.phys_alignment = alignment;
req.preferred_heap = type;
@@ -129,17 +217,36 @@ static inline amdgpu_bo_handle gpu_mem_alloc(
r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ return NULL;
+
+ if (vmc_addr && va_handle) {
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ size, alignment, 0, vmc_addr,
+ va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ goto error_free_bo;
+
+ r = amdgpu_bo_va_op(buf_handle, 0, size, *vmc_addr, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ goto error_free_va;
+ }
+
+ return buf_handle;
- r = amdgpu_va_range_alloc(device_handle,
- amdgpu_gpu_va_range_general,
- size, alignment, 0, vmc_addr,
- va_handle, 0);
+error_free_va:
+ r = amdgpu_va_range_free(*va_handle);
CU_ASSERT_EQUAL(r, 0);
- r = amdgpu_bo_va_op(buf_handle, 0, size, *vmc_addr, 0, AMDGPU_VA_OP_MAP);
+error_free_bo:
+ r = amdgpu_bo_free(buf_handle);
CU_ASSERT_EQUAL(r, 0);
- return buf_handle;
+ return NULL;
}
static inline int gpu_mem_free(amdgpu_bo_handle bo,
@@ -149,28 +256,35 @@ static inline int gpu_mem_free(amdgpu_bo_handle bo,
{
int r;
- r = amdgpu_bo_va_op(bo, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
- CU_ASSERT_EQUAL(r, 0);
+ if (!bo)
+ return 0;
- r = amdgpu_va_range_free(va_handle);
- CU_ASSERT_EQUAL(r, 0);
+ if (va_handle) {
+ r = amdgpu_bo_va_op(bo, 0, size, vmc_addr, 0,
+ AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ return r;
+
+ r = amdgpu_va_range_free(va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ return r;
+ }
r = amdgpu_bo_free(bo);
CU_ASSERT_EQUAL(r, 0);
- return 0;
+ return r;
}
static inline int
-amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,
- unsigned alignment, unsigned heap, uint64_t flags,
- amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address,
- amdgpu_va_handle *va_handle)
+amdgpu_bo_alloc_wrap(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t flags,
+ amdgpu_bo_handle *bo)
{
struct amdgpu_bo_alloc_request request = {};
amdgpu_bo_handle buf_handle;
- amdgpu_va_handle handle;
- uint64_t vmc_addr;
int r;
request.alloc_size = size;
@@ -182,36 +296,25 @@ amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,
if (r)
return r;
- r = amdgpu_va_range_alloc(dev,
- amdgpu_gpu_va_range_general,
- size, alignment, 0, &vmc_addr,
- &handle, 0);
- if (r)
- goto error_va_alloc;
-
- r = amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_MAP);
- if (r)
- goto error_va_map;
-
- r = amdgpu_bo_cpu_map(buf_handle, cpu);
- if (r)
- goto error_cpu_map;
-
*bo = buf_handle;
- *mc_address = vmc_addr;
- *va_handle = handle;
return 0;
+}
-error_cpu_map:
- amdgpu_bo_cpu_unmap(buf_handle);
-
-error_va_map:
- amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
+int amdgpu_bo_alloc_and_map_raw(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t alloc_flags,
+ uint64_t mapping_flags, amdgpu_bo_handle *bo, void **cpu,
+ uint64_t *mc_address,
+ amdgpu_va_handle *va_handle);
-error_va_alloc:
- amdgpu_bo_free(buf_handle);
- return r;
+static inline int
+amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t alloc_flags,
+ amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address,
+ amdgpu_va_handle *va_handle)
+{
+ return amdgpu_bo_alloc_and_map_raw(dev, size, alignment, heap,
+ alloc_flags, 0, bo, cpu, mc_address, va_handle);
}
static inline int
@@ -236,4 +339,35 @@ amdgpu_get_bo_list(amdgpu_device_handle dev, amdgpu_bo_handle bo1,
return amdgpu_bo_list_create(dev, bo2 ? 2 : 1, resources, NULL, list);
}
+
+static inline CU_ErrorCode amdgpu_set_suite_active(const char *suite_name,
+ CU_BOOL active)
+{
+ CU_ErrorCode r = CU_set_suite_active(CU_get_suite(suite_name), active);
+
+ if (r != CUE_SUCCESS)
+ fprintf(stderr, "Failed to obtain suite %s\n", suite_name);
+
+ return r;
+}
+
+static inline CU_ErrorCode amdgpu_set_test_active(const char *suite_name,
+ const char *test_name, CU_BOOL active)
+{
+ CU_ErrorCode r;
+ CU_pSuite pSuite = CU_get_suite(suite_name);
+
+ if (!pSuite) {
+ fprintf(stderr, "Failed to obtain suite %s\n",
+ suite_name);
+ return CUE_NOSUITE;
+ }
+
+ r = CU_set_test_active(CU_get_test(pSuite, test_name), active);
+ if (r != CUE_SUCCESS)
+ fprintf(stderr, "Failed to obtain test %s\n", test_name);
+
+ return r;
+}
+
#endif /* #ifdef _AMDGPU_TEST_H_ */
diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c
index bfda21b1..dbae4d53 100644
--- a/tests/amdgpu/basic_tests.c
+++ b/tests/amdgpu/basic_tests.c
@@ -21,46 +21,55 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
+#include <sys/wait.h>
#include "CUnit/Basic.h"
#include "amdgpu_test.h"
#include "amdgpu_drm.h"
+#include "util_math.h"
static amdgpu_device_handle device_handle;
static uint32_t major_version;
static uint32_t minor_version;
+static uint32_t family_id;
static void amdgpu_query_info_test(void);
-static void amdgpu_memory_alloc(void);
static void amdgpu_command_submission_gfx(void);
static void amdgpu_command_submission_compute(void);
+static void amdgpu_command_submission_multi_fence(void);
static void amdgpu_command_submission_sdma(void);
static void amdgpu_userptr_test(void);
static void amdgpu_semaphore_test(void);
+static void amdgpu_sync_dependency_test(void);
+static void amdgpu_bo_eviction_test(void);
static void amdgpu_command_submission_write_linear_helper(unsigned ip_type);
static void amdgpu_command_submission_const_fill_helper(unsigned ip_type);
static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type);
-
+static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
+ unsigned ip_type,
+ int instance, int pm4_dw, uint32_t *pm4_src,
+ int res_cnt, amdgpu_bo_handle *resources,
+ struct amdgpu_cs_ib_info *ib_info,
+ struct amdgpu_cs_request *ibs_request);
+
CU_TestInfo basic_tests[] = {
{ "Query Info Test", amdgpu_query_info_test },
- { "Memory alloc Test", amdgpu_memory_alloc },
{ "Userptr Test", amdgpu_userptr_test },
+ { "bo eviction Test", amdgpu_bo_eviction_test },
{ "Command submission Test (GFX)", amdgpu_command_submission_gfx },
{ "Command submission Test (Compute)", amdgpu_command_submission_compute },
+ { "Command submission Test (Multi-Fence)", amdgpu_command_submission_multi_fence },
{ "Command submission Test (SDMA)", amdgpu_command_submission_sdma },
{ "SW semaphore Test", amdgpu_semaphore_test },
+ { "Sync dependency Test", amdgpu_sync_dependency_test },
CU_TEST_INFO_NULL,
};
#define BUFFER_SIZE (8 * 1024)
@@ -197,22 +206,170 @@ CU_TestInfo basic_tests[] = {
# define PACKET3_DMA_DATA_CMD_DAIC (1 << 29)
# define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30)
+#define SDMA_PACKET_SI(op, b, t, s, cnt) ((((op) & 0xF) << 28) | \
+ (((b) & 0x1) << 26) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((cnt) & 0xFFFFF) << 0))
+#define SDMA_OPCODE_COPY_SI 3
+#define SDMA_OPCODE_CONSTANT_FILL_SI 13
+#define SDMA_NOP_SI 0xf
+#define GFX_COMPUTE_NOP_SI 0x80000000
+#define PACKET3_DMA_DATA_SI 0x41
+# define PACKET3_DMA_DATA_SI_ENGINE(x) ((x) << 27)
+ /* 0 - ME
+ * 1 - PFP
+ */
+# define PACKET3_DMA_DATA_SI_DST_SEL(x) ((x) << 20)
+ /* 0 - DST_ADDR using DAS
+ * 1 - GDS
+ * 3 - DST_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_SI_SRC_SEL(x) ((x) << 29)
+ /* 0 - SRC_ADDR using SAS
+ * 1 - GDS
+ * 2 - DATA
+ * 3 - SRC_ADDR using L2
+ */
+# define PACKET3_DMA_DATA_SI_CP_SYNC (1 << 31)
+
+
+#define PKT3_CONTEXT_CONTROL 0x28
+#define CONTEXT_CONTROL_LOAD_ENABLE(x) (((unsigned)(x) & 0x1) << 31)
+#define CONTEXT_CONTROL_LOAD_CE_RAM(x) (((unsigned)(x) & 0x1) << 28)
+#define CONTEXT_CONTROL_SHADOW_ENABLE(x) (((unsigned)(x) & 0x1) << 31)
+
+#define PKT3_CLEAR_STATE 0x12
+
+#define PKT3_SET_SH_REG 0x76
+#define PACKET3_SET_SH_REG_START 0x00002c00
+
+#define PACKET3_DISPATCH_DIRECT 0x15
+
+
+/* gfx 8 */
+#define mmCOMPUTE_PGM_LO 0x2e0c
+#define mmCOMPUTE_PGM_RSRC1 0x2e12
+#define mmCOMPUTE_TMPRING_SIZE 0x2e18
+#define mmCOMPUTE_USER_DATA_0 0x2e40
+#define mmCOMPUTE_USER_DATA_1 0x2e41
+#define mmCOMPUTE_RESOURCE_LIMITS 0x2e15
+#define mmCOMPUTE_NUM_THREAD_X 0x2e07
+
+
+
+#define SWAP_32(num) (((num & 0xff000000) >> 24) | \
+ ((num & 0x0000ff00) << 8) | \
+ ((num & 0x00ff0000) >> 8) | \
+ ((num & 0x000000ff) << 24))
+
+
+/* Shader code
+ * void main()
+{
+
+ float x = some_input;
+ for (unsigned i = 0; i < 1000000; i++)
+ x = sin(x);
+
+ u[0] = 42u;
+}
+*/
+
+static uint32_t shader_bin[] = {
+ SWAP_32(0x800082be), SWAP_32(0x02ff08bf), SWAP_32(0x7f969800), SWAP_32(0x040085bf),
+ SWAP_32(0x02810281), SWAP_32(0x02ff08bf), SWAP_32(0x7f969800), SWAP_32(0xfcff84bf),
+ SWAP_32(0xff0083be), SWAP_32(0x00f00000), SWAP_32(0xc10082be), SWAP_32(0xaa02007e),
+ SWAP_32(0x000070e0), SWAP_32(0x00000080), SWAP_32(0x000081bf)
+};
+
+#define CODE_OFFSET 512
+#define DATA_OFFSET 1024
+
+
+int amdgpu_bo_alloc_and_map_raw(amdgpu_device_handle dev, unsigned size,
+ unsigned alignment, unsigned heap, uint64_t alloc_flags,
+ uint64_t mapping_flags, amdgpu_bo_handle *bo, void **cpu,
+ uint64_t *mc_address,
+ amdgpu_va_handle *va_handle)
+{
+ struct amdgpu_bo_alloc_request request = {};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle 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)
+ return r;
+
+ r = amdgpu_va_range_alloc(dev,
+ amdgpu_gpu_va_range_general,
+ size, alignment, 0, &vmc_addr,
+ &handle, 0);
+ if (r)
+ goto error_va_alloc;
+
+ r = amdgpu_bo_va_op_raw(dev, buf_handle, 0, ALIGN(size, getpagesize()), vmc_addr,
+ AMDGPU_VM_PAGE_READABLE |
+ AMDGPU_VM_PAGE_WRITEABLE |
+ AMDGPU_VM_PAGE_EXECUTABLE |
+ mapping_flags,
+ AMDGPU_VA_OP_MAP);
+ if (r)
+ goto error_va_map;
+
+ r = amdgpu_bo_cpu_map(buf_handle, cpu);
+ if (r)
+ goto error_cpu_map;
+
+ *bo = buf_handle;
+ *mc_address = vmc_addr;
+ *va_handle = handle;
+
+ return 0;
+
+ error_cpu_map:
+ amdgpu_bo_cpu_unmap(buf_handle);
+
+ error_va_map:
+ amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
+
+ error_va_alloc:
+ amdgpu_bo_free(buf_handle);
+ return r;
+}
+
+
+
int suite_basic_tests_init(void)
{
+ struct amdgpu_gpu_info gpu_info = {0};
int r;
r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
&minor_version, &device_handle);
- if (r == 0)
- return CUE_SUCCESS;
- else {
+ if (r) {
if ((r == -EACCES) && (errno == EACCES))
printf("\n\nError:%s. "
"Hint:Try to run this test program as root.",
strerror(errno));
return CUE_SINIT_FAILED;
}
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = gpu_info.family_id;
+
+ return CUE_SUCCESS;
}
int suite_basic_tests_clean(void)
@@ -239,53 +396,6 @@ static void amdgpu_query_info_test(void)
CU_ASSERT_EQUAL(r, 0);
}
-static void amdgpu_memory_alloc(void)
-{
- amdgpu_bo_handle bo;
- amdgpu_va_handle va_handle;
- uint64_t bo_mc;
- int r;
-
- /* Test visible VRAM */
- bo = gpu_mem_alloc(device_handle,
- 4096, 4096,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
- &bo_mc, &va_handle);
-
- r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
- CU_ASSERT_EQUAL(r, 0);
-
- /* Test invisible VRAM */
- bo = gpu_mem_alloc(device_handle,
- 4096, 4096,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
- &bo_mc, &va_handle);
-
- r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
- CU_ASSERT_EQUAL(r, 0);
-
- /* Test GART Cacheable */
- bo = gpu_mem_alloc(device_handle,
- 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- 0, &bo_mc, &va_handle);
-
- r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
- CU_ASSERT_EQUAL(r, 0);
-
- /* Test GART USWC */
- bo = gpu_mem_alloc(device_handle,
- 4096, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- AMDGPU_GEM_CREATE_CPU_GTT_USWC,
- &bo_mc, &va_handle);
-
- r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
- CU_ASSERT_EQUAL(r, 0);
-}
-
static void amdgpu_command_submission_gfx_separate_ibs(void)
{
amdgpu_context_handle context_handle;
@@ -299,7 +409,7 @@ static void amdgpu_command_submission_gfx_separate_ibs(void)
uint32_t expired;
amdgpu_bo_list_handle bo_list;
amdgpu_va_handle va_handle, va_handle_ce;
- int r;
+ int r, i = 0;
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
@@ -324,12 +434,14 @@ static void amdgpu_command_submission_gfx_separate_ibs(void)
/* IT_SET_CE_DE_COUNTERS */
ptr = ib_result_ce_cpu;
- ptr[0] = 0xc0008900;
- ptr[1] = 0;
- ptr[2] = 0xc0008400;
- ptr[3] = 1;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
ib_info[0].ib_mc_address = ib_result_ce_mc_address;
- ib_info[0].size = 4;
+ ib_info[0].size = i;
ib_info[0].flags = AMDGPU_IB_FLAG_CE;
/* IT_WAIT_ON_CE_COUNTER */
@@ -388,7 +500,7 @@ static void amdgpu_command_submission_gfx_shared_ib(void)
uint32_t expired;
amdgpu_bo_list_handle bo_list;
amdgpu_va_handle va_handle;
- int r;
+ int r, i = 0;
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
@@ -407,12 +519,14 @@ static void amdgpu_command_submission_gfx_shared_ib(void)
/* IT_SET_CE_DE_COUNTERS */
ptr = ib_result_cpu;
- ptr[0] = 0xc0008900;
- ptr[1] = 0;
- ptr[2] = 0xc0008400;
- ptr[3] = 1;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
ib_info[0].ib_mc_address = ib_result_mc_address;
- ib_info[0].size = 4;
+ ib_info[0].size = i;
ib_info[0].flags = AMDGPU_IB_FLAG_CE;
ptr = (uint32_t *)ib_result_cpu + 4;
@@ -467,6 +581,156 @@ static void amdgpu_command_submission_gfx_cp_copy_data(void)
amdgpu_command_submission_copy_linear_helper(AMDGPU_HW_IP_GFX);
}
+static void amdgpu_bo_eviction_test(void)
+{
+ const int sdma_write_length = 1024;
+ const int pm4_dw = 256;
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle bo1, bo2, vram_max[2], gtt_max[2];
+ amdgpu_bo_handle *resources;
+ uint32_t *pm4;
+ struct amdgpu_cs_ib_info *ib_info;
+ struct amdgpu_cs_request *ibs_request;
+ uint64_t bo1_mc, bo2_mc;
+ volatile unsigned char *bo1_cpu, *bo2_cpu;
+ int i, j, r, loop1, loop2;
+ uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
+ amdgpu_va_handle bo1_va_handle, bo2_va_handle;
+ struct amdgpu_heap_info vram_info, gtt_info;
+
+ pm4 = calloc(pm4_dw, sizeof(*pm4));
+ CU_ASSERT_NOT_EQUAL(pm4, NULL);
+
+ ib_info = calloc(1, sizeof(*ib_info));
+ CU_ASSERT_NOT_EQUAL(ib_info, NULL);
+
+ ibs_request = calloc(1, sizeof(*ibs_request));
+ CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* prepare resource */
+ resources = calloc(4, sizeof(amdgpu_bo_handle));
+ CU_ASSERT_NOT_EQUAL(resources, NULL);
+
+ r = amdgpu_query_heap_info(device_handle, AMDGPU_GEM_DOMAIN_VRAM,
+ 0, &vram_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_wrap(device_handle, vram_info.max_allocation, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0, &vram_max[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_alloc_wrap(device_handle, vram_info.max_allocation, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0, &vram_max[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_query_heap_info(device_handle, AMDGPU_GEM_DOMAIN_GTT,
+ 0, &gtt_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_wrap(device_handle, gtt_info.max_allocation, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, &gtt_max[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_alloc_wrap(device_handle, gtt_info.max_allocation, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, &gtt_max[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+
+ loop1 = loop2 = 0;
+ /* run 9 circle to test all mapping combination */
+ while(loop1 < 2) {
+ while(loop2 < 2) {
+ /* allocate UC bo1for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop1], &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,
+ gtt_flags[loop2], &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] = vram_max[loop2];
+ resources[3] = gtt_max[loop2];
+
+ /* fulfill PM4: test DMA copy linear */
+ i = j = 0;
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI, 0, 0, 0,
+ sdma_write_length);
+ pm4[i++] = 0xffffffff & bo2_mc;
+ pm4[i++] = 0xffffffff & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ } else {
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else
+ pm4[i++] = sdma_write_length;
+ pm4[i++] = 0;
+ pm4[i++] = 0xffffffff & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ pm4[i++] = 0xffffffff & bo2_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ }
+
+ amdgpu_test_exec_cs_helper(context_handle,
+ AMDGPU_HW_IP_DMA, 0,
+ i, pm4,
+ 4, resources,
+ ib_info, ibs_request);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ while(i < sdma_write_length) {
+ CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa);
+ }
+ 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);
+ loop2++;
+ }
+ loop2 = 0;
+ loop1++;
+ }
+ amdgpu_bo_free(vram_max[0]);
+ amdgpu_bo_free(vram_max[1]);
+ amdgpu_bo_free(gtt_max[0]);
+ amdgpu_bo_free(gtt_max[1]);
+ /* clean resources */
+ free(resources);
+ free(ibs_request);
+ free(ib_info);
+ free(pm4);
+
+ /* end of test */
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+
static void amdgpu_command_submission_gfx(void)
{
/* write data using the CP */
@@ -493,10 +757,19 @@ static void amdgpu_semaphore_test(void)
struct amdgpu_cs_fence fence_status = {0};
uint32_t *ptr;
uint32_t expired;
+ uint32_t sdma_nop, gfx_nop;
amdgpu_bo_list_handle bo_list[2];
amdgpu_va_handle va_handle[2];
int r, i;
+ if (family_id == AMDGPU_FAMILY_SI) {
+ sdma_nop = SDMA_PACKET_SI(SDMA_NOP_SI, 0, 0, 0, 0);
+ gfx_nop = GFX_COMPUTE_NOP_SI;
+ } else {
+ sdma_nop = SDMA_PKT_HEADER_OP(SDMA_NOP);
+ gfx_nop = GFX_COMPUTE_NOP;
+ }
+
r = amdgpu_cs_create_semaphore(&sem);
CU_ASSERT_EQUAL(r, 0);
for (i = 0; i < 2; i++) {
@@ -516,7 +789,7 @@ static void amdgpu_semaphore_test(void)
/* 1. same context different engine */
ptr = ib_result_cpu[0];
- ptr[0] = SDMA_NOP;
+ ptr[0] = sdma_nop;
ib_info[0].ib_mc_address = ib_result_mc_address[0];
ib_info[0].size = 1;
@@ -533,7 +806,7 @@ static void amdgpu_semaphore_test(void)
r = amdgpu_cs_wait_semaphore(context_handle[0], AMDGPU_HW_IP_GFX, 0, 0, sem);
CU_ASSERT_EQUAL(r, 0);
ptr = ib_result_cpu[1];
- ptr[0] = GFX_COMPUTE_NOP;
+ ptr[0] = gfx_nop;
ib_info[1].ib_mc_address = ib_result_mc_address[1];
ib_info[1].size = 1;
@@ -557,7 +830,7 @@ static void amdgpu_semaphore_test(void)
/* 2. same engine different context */
ptr = ib_result_cpu[0];
- ptr[0] = GFX_COMPUTE_NOP;
+ ptr[0] = gfx_nop;
ib_info[0].ib_mc_address = ib_result_mc_address[0];
ib_info[0].size = 1;
@@ -574,7 +847,7 @@ static void amdgpu_semaphore_test(void)
r = amdgpu_cs_wait_semaphore(context_handle[1], AMDGPU_HW_IP_GFX, 0, 0, sem);
CU_ASSERT_EQUAL(r, 0);
ptr = ib_result_cpu[1];
- ptr[0] = GFX_COMPUTE_NOP;
+ ptr[0] = gfx_nop;
ib_info[1].ib_mc_address = ib_result_mc_address[1];
ib_info[1].size = 1;
@@ -595,6 +868,7 @@ static void amdgpu_semaphore_test(void)
500000000, 0, &expired);
CU_ASSERT_EQUAL(r, 0);
CU_ASSERT_EQUAL(expired, true);
+
for (i = 0; i < 2; i++) {
r = amdgpu_bo_unmap_and_free(ib_result_handle[i], va_handle[i],
ib_result_mc_address[i], 4096);
@@ -622,14 +896,18 @@ static void amdgpu_command_submission_compute_nop(void)
struct amdgpu_cs_fence fence_status;
uint32_t *ptr;
uint32_t expired;
- int i, r, instance;
+ int r, instance;
amdgpu_bo_list_handle bo_list;
amdgpu_va_handle va_handle;
+ struct drm_amdgpu_info_hw_ip info;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_COMPUTE, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
- for (instance = 0; instance < 8; instance++) {
+ for (instance = 0; (1 << instance) & info.available_rings; instance++) {
r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
AMDGPU_GEM_DOMAIN_GTT, 0,
&ib_result_handle, &ib_result_cpu,
@@ -641,8 +919,8 @@ static void amdgpu_command_submission_compute_nop(void)
CU_ASSERT_EQUAL(r, 0);
ptr = ib_result_cpu;
- for (i = 0; i < 16; ++i)
- ptr[i] = 0xffff1000;
+ memset(ptr, 0, 16);
+ ptr[0]=PACKET3(PACKET3_NOP, 14);
memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
ib_info.ib_mc_address = ib_result_mc_address;
@@ -805,9 +1083,10 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
struct amdgpu_cs_request *ibs_request;
uint64_t bo_mc;
volatile uint32_t *bo_cpu;
- int i, j, r, loop;
+ int i, j, r, loop, ring_id;
uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
amdgpu_va_handle va_handle;
+ struct drm_amdgpu_info_hw_ip hw_ip_info;
pm4 = calloc(pm4_dw, sizeof(*pm4));
CU_ASSERT_NOT_EQUAL(pm4, NULL);
@@ -818,6 +1097,9 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
ibs_request = calloc(1, sizeof(*ibs_request));
CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+ r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info);
+ CU_ASSERT_EQUAL(r, 0);
+
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
@@ -825,58 +1107,66 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
resources = calloc(1, sizeof(amdgpu_bo_handle));
CU_ASSERT_NOT_EQUAL(resources, NULL);
- loop = 0;
- while(loop < 2) {
- /* allocate UC bo for sDMA use */
- r = amdgpu_bo_alloc_and_map(device_handle,
- sdma_write_length * sizeof(uint32_t),
- 4096, AMDGPU_GEM_DOMAIN_GTT,
- gtt_flags[loop], &bo, (void**)&bo_cpu,
- &bo_mc, &va_handle);
- CU_ASSERT_EQUAL(r, 0);
+ for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) {
+ loop = 0;
+ while(loop < 2) {
+ /* allocate UC bo for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length * sizeof(uint32_t),
+ 4096, AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop], &bo, (void**)&bo_cpu,
+ &bo_mc, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
- /* clear bo */
- memset((void*)bo_cpu, 0, sdma_write_length * sizeof(uint32_t));
-
-
- resources[0] = bo;
-
- /* fulfill PM4: test DMA write-linear */
- i = j = 0;
- if (ip_type == AMDGPU_HW_IP_DMA) {
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
- SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
- pm4[i++] = 0xffffffff & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- pm4[i++] = sdma_write_length;
- while(j++ < sdma_write_length)
- pm4[i++] = 0xdeadbeaf;
- } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
- (ip_type == AMDGPU_HW_IP_COMPUTE)) {
- pm4[i++] = PACKET3(PACKET3_WRITE_DATA, 2 + sdma_write_length);
- pm4[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
- pm4[i++] = 0xfffffffc & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- while(j++ < sdma_write_length)
- pm4[i++] = 0xdeadbeaf;
- }
+ /* clear bo */
+ memset((void*)bo_cpu, 0, sdma_write_length * sizeof(uint32_t));
- amdgpu_test_exec_cs_helper(context_handle,
- ip_type, 0,
- i, pm4,
- 1, resources,
- ib_info, ibs_request);
+ resources[0] = bo;
- /* verify if SDMA test result meets with expected */
- i = 0;
- while(i < sdma_write_length) {
- CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
- }
+ /* fulfill PM4: test DMA write-linear */
+ i = j = 0;
+ if (ip_type == AMDGPU_HW_IP_DMA) {
+ if (family_id == AMDGPU_FAMILY_SI)
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_WRITE, 0, 0, 0,
+ sdma_write_length);
+ else
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
+ SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
+ pm4[i++] = 0xffffffff & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else if (family_id != AMDGPU_FAMILY_SI)
+ pm4[i++] = sdma_write_length;
+ while(j++ < sdma_write_length)
+ pm4[i++] = 0xdeadbeaf;
+ } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
+ (ip_type == AMDGPU_HW_IP_COMPUTE)) {
+ pm4[i++] = PACKET3(PACKET3_WRITE_DATA, 2 + sdma_write_length);
+ pm4[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ while(j++ < sdma_write_length)
+ pm4[i++] = 0xdeadbeaf;
+ }
- r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
- sdma_write_length * sizeof(uint32_t));
- CU_ASSERT_EQUAL(r, 0);
- loop++;
+ amdgpu_test_exec_cs_helper(context_handle,
+ ip_type, ring_id,
+ i, pm4,
+ 1, resources,
+ ib_info, ibs_request);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ while(i < sdma_write_length) {
+ CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
+ }
+
+ r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
+ sdma_write_length * sizeof(uint32_t));
+ CU_ASSERT_EQUAL(r, 0);
+ loop++;
+ }
}
/* clean resources */
free(resources);
@@ -906,9 +1196,10 @@ static void amdgpu_command_submission_const_fill_helper(unsigned ip_type)
struct amdgpu_cs_request *ibs_request;
uint64_t bo_mc;
volatile uint32_t *bo_cpu;
- int i, j, r, loop;
+ int i, j, r, loop, ring_id;
uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
amdgpu_va_handle va_handle;
+ struct drm_amdgpu_info_hw_ip hw_ip_info;
pm4 = calloc(pm4_dw, sizeof(*pm4));
CU_ASSERT_NOT_EQUAL(pm4, NULL);
@@ -919,6 +1210,9 @@ static void amdgpu_command_submission_const_fill_helper(unsigned ip_type)
ibs_request = calloc(1, sizeof(*ibs_request));
CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+ r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info);
+ CU_ASSERT_EQUAL(r, 0);
+
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
@@ -926,60 +1220,86 @@ static void amdgpu_command_submission_const_fill_helper(unsigned ip_type)
resources = calloc(1, sizeof(amdgpu_bo_handle));
CU_ASSERT_NOT_EQUAL(resources, NULL);
- loop = 0;
- while(loop < 2) {
- /* allocate UC bo for sDMA use */
- r = amdgpu_bo_alloc_and_map(device_handle,
- sdma_write_length, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- gtt_flags[loop], &bo, (void**)&bo_cpu,
- &bo_mc, &va_handle);
- CU_ASSERT_EQUAL(r, 0);
+ for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) {
+ loop = 0;
+ while(loop < 2) {
+ /* allocate UC bo for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop], &bo, (void**)&bo_cpu,
+ &bo_mc, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
- /* clear bo */
- memset((void*)bo_cpu, 0, sdma_write_length);
-
- resources[0] = bo;
-
- /* fulfill PM4: test DMA const fill */
- i = j = 0;
- if (ip_type == AMDGPU_HW_IP_DMA) {
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0,
- SDMA_CONSTANT_FILL_EXTRA_SIZE(2));
- pm4[i++] = 0xffffffff & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- pm4[i++] = 0xdeadbeaf;
- pm4[i++] = sdma_write_length;
- } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
- (ip_type == AMDGPU_HW_IP_COMPUTE)) {
- pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
- pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
- PACKET3_DMA_DATA_DST_SEL(0) |
- PACKET3_DMA_DATA_SRC_SEL(2) |
- PACKET3_DMA_DATA_CP_SYNC;
- pm4[i++] = 0xdeadbeaf;
- pm4[i++] = 0;
- pm4[i++] = 0xfffffffc & bo_mc;
- pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- pm4[i++] = sdma_write_length;
- }
+ /* clear bo */
+ memset((void*)bo_cpu, 0, sdma_write_length);
- amdgpu_test_exec_cs_helper(context_handle,
- ip_type, 0,
- i, pm4,
- 1, resources,
- ib_info, ibs_request);
+ resources[0] = bo;
- /* verify if SDMA test result meets with expected */
- i = 0;
- while(i < (sdma_write_length / 4)) {
- CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
- }
+ /* fulfill PM4: test DMA const fill */
+ i = j = 0;
+ if (ip_type == AMDGPU_HW_IP_DMA) {
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_CONSTANT_FILL_SI,
+ 0, 0, 0,
+ sdma_write_length / 4);
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 16;
+ } else {
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0,
+ SDMA_CONSTANT_FILL_EXTRA_SIZE(2));
+ pm4[i++] = 0xffffffff & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = 0xdeadbeaf;
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else
+ pm4[i++] = sdma_write_length;
+ }
+ } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
+ (ip_type == AMDGPU_HW_IP_COMPUTE)) {
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4);
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) |
+ PACKET3_DMA_DATA_SI_DST_SEL(0) |
+ PACKET3_DMA_DATA_SI_SRC_SEL(2) |
+ PACKET3_DMA_DATA_SI_CP_SYNC;
+ pm4[i++] = 0xffffffff & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = sdma_write_length;
+ } else {
+ pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
+ pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
+ PACKET3_DMA_DATA_DST_SEL(0) |
+ PACKET3_DMA_DATA_SRC_SEL(2) |
+ PACKET3_DMA_DATA_CP_SYNC;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = 0;
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = sdma_write_length;
+ }
+ }
- r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
- sdma_write_length);
- CU_ASSERT_EQUAL(r, 0);
- loop++;
+ amdgpu_test_exec_cs_helper(context_handle,
+ ip_type, ring_id,
+ i, pm4,
+ 1, resources,
+ ib_info, ibs_request);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ while(i < (sdma_write_length / 4)) {
+ CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
+ }
+
+ r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
+ sdma_write_length);
+ CU_ASSERT_EQUAL(r, 0);
+ loop++;
+ }
}
/* clean resources */
free(resources);
@@ -1009,9 +1329,10 @@ static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type)
struct amdgpu_cs_request *ibs_request;
uint64_t bo1_mc, bo2_mc;
volatile unsigned char *bo1_cpu, *bo2_cpu;
- int i, j, r, loop1, loop2;
+ int i, j, r, loop1, loop2, ring_id;
uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
amdgpu_va_handle bo1_va_handle, bo2_va_handle;
+ struct drm_amdgpu_info_hw_ip hw_ip_info;
pm4 = calloc(pm4_dw, sizeof(*pm4));
CU_ASSERT_NOT_EQUAL(pm4, NULL);
@@ -1022,6 +1343,9 @@ static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type)
ibs_request = calloc(1, sizeof(*ibs_request));
CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
+ r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info);
+ CU_ASSERT_EQUAL(r, 0);
+
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
@@ -1029,81 +1353,111 @@ static void amdgpu_command_submission_copy_linear_helper(unsigned ip_type)
resources = calloc(2, sizeof(amdgpu_bo_handle));
CU_ASSERT_NOT_EQUAL(resources, NULL);
- loop1 = loop2 = 0;
- /* run 9 circle to test all mapping combination */
- while(loop1 < 2) {
- while(loop2 < 2) {
- /* allocate UC bo1for sDMA use */
- r = amdgpu_bo_alloc_and_map(device_handle,
- sdma_write_length, 4096,
- AMDGPU_GEM_DOMAIN_GTT,
- gtt_flags[loop1], &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,
- gtt_flags[loop2], &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;
-
- /* fulfill PM4: test DMA copy linear */
- i = j = 0;
- if (ip_type == AMDGPU_HW_IP_DMA) {
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
- pm4[i++] = sdma_write_length;
- pm4[i++] = 0;
- pm4[i++] = 0xffffffff & bo1_mc;
- pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
- pm4[i++] = 0xffffffff & bo2_mc;
- pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
- } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
- (ip_type == AMDGPU_HW_IP_COMPUTE)) {
- pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
- pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
- PACKET3_DMA_DATA_DST_SEL(0) |
- PACKET3_DMA_DATA_SRC_SEL(0) |
- PACKET3_DMA_DATA_CP_SYNC;
- pm4[i++] = 0xfffffffc & bo1_mc;
- pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
- pm4[i++] = 0xfffffffc & bo2_mc;
- pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
- pm4[i++] = sdma_write_length;
- }
-
- amdgpu_test_exec_cs_helper(context_handle,
- ip_type, 0,
- i, pm4,
- 2, resources,
- ib_info, ibs_request);
-
- /* verify if SDMA test result meets with expected */
- i = 0;
- while(i < sdma_write_length) {
- CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa);
+ for (ring_id = 0; (1 << ring_id) & hw_ip_info.available_rings; ring_id++) {
+ loop1 = loop2 = 0;
+ /* run 9 circle to test all mapping combination */
+ while(loop1 < 2) {
+ while(loop2 < 2) {
+ /* allocate UC bo1for sDMA use */
+ r = amdgpu_bo_alloc_and_map(device_handle,
+ sdma_write_length, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ gtt_flags[loop1], &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,
+ gtt_flags[loop2], &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;
+
+ /* fulfill PM4: test DMA copy linear */
+ i = j = 0;
+ if (ip_type == AMDGPU_HW_IP_DMA) {
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_COPY_SI,
+ 0, 0, 0,
+ sdma_write_length);
+ pm4[i++] = 0xffffffff & bo2_mc;
+ pm4[i++] = 0xffffffff & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ } else {
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY,
+ SDMA_COPY_SUB_OPCODE_LINEAR,
+ 0);
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else
+ pm4[i++] = sdma_write_length;
+ pm4[i++] = 0;
+ pm4[i++] = 0xffffffff & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ pm4[i++] = 0xffffffff & bo2_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ }
+ } else if ((ip_type == AMDGPU_HW_IP_GFX) ||
+ (ip_type == AMDGPU_HW_IP_COMPUTE)) {
+ if (family_id == AMDGPU_FAMILY_SI) {
+ pm4[i++] = PACKET3(PACKET3_DMA_DATA_SI, 4);
+ pm4[i++] = 0xfffffffc & bo1_mc;
+ pm4[i++] = PACKET3_DMA_DATA_SI_ENGINE(0) |
+ PACKET3_DMA_DATA_SI_DST_SEL(0) |
+ PACKET3_DMA_DATA_SI_SRC_SEL(0) |
+ PACKET3_DMA_DATA_SI_CP_SYNC |
+ (0xffff00000000 & bo1_mc) >> 32;
+ pm4[i++] = 0xfffffffc & bo2_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ pm4[i++] = sdma_write_length;
+ } else {
+ pm4[i++] = PACKET3(PACKET3_DMA_DATA, 5);
+ pm4[i++] = PACKET3_DMA_DATA_ENGINE(0) |
+ PACKET3_DMA_DATA_DST_SEL(0) |
+ PACKET3_DMA_DATA_SRC_SEL(0) |
+ PACKET3_DMA_DATA_CP_SYNC;
+ pm4[i++] = 0xfffffffc & bo1_mc;
+ pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
+ pm4[i++] = 0xfffffffc & bo2_mc;
+ pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
+ pm4[i++] = sdma_write_length;
+ }
+ }
+
+ amdgpu_test_exec_cs_helper(context_handle,
+ ip_type, ring_id,
+ i, pm4,
+ 2, resources,
+ ib_info, ibs_request);
+
+ /* verify if SDMA test result meets with expected */
+ i = 0;
+ while(i < sdma_write_length) {
+ CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa);
+ }
+ 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);
+ loop2++;
}
- 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);
- loop2++;
+ loop1++;
}
- loop1++;
}
/* clean resources */
free(resources);
@@ -1128,6 +1482,106 @@ static void amdgpu_command_submission_sdma(void)
amdgpu_command_submission_sdma_copy_linear();
}
+static void amdgpu_command_submission_multi_fence_wait_all(bool wait_all)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
+ void *ib_result_cpu, *ib_result_ce_cpu;
+ uint64_t ib_result_mc_address, ib_result_ce_mc_address;
+ struct amdgpu_cs_request ibs_request[2] = {0};
+ struct amdgpu_cs_ib_info ib_info[2];
+ struct amdgpu_cs_fence fence_status[2] = {0};
+ uint32_t *ptr;
+ uint32_t expired;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle, va_handle_ce;
+ int r;
+ int i = 0, ib_cs_num = 2;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_ce_handle, &ib_result_ce_cpu,
+ &ib_result_ce_mc_address, &va_handle_ce);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle,
+ ib_result_ce_handle, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
+
+ /* IT_SET_CE_DE_COUNTERS */
+ ptr = ib_result_ce_cpu;
+ if (family_id != AMDGPU_FAMILY_SI) {
+ ptr[i++] = 0xc0008900;
+ ptr[i++] = 0;
+ }
+ ptr[i++] = 0xc0008400;
+ ptr[i++] = 1;
+ ib_info[0].ib_mc_address = ib_result_ce_mc_address;
+ ib_info[0].size = i;
+ ib_info[0].flags = AMDGPU_IB_FLAG_CE;
+
+ /* IT_WAIT_ON_CE_COUNTER */
+ ptr = ib_result_cpu;
+ ptr[0] = 0xc0008600;
+ ptr[1] = 0x00000001;
+ ib_info[1].ib_mc_address = ib_result_mc_address;
+ ib_info[1].size = 2;
+
+ for (i = 0; i < ib_cs_num; i++) {
+ ibs_request[i].ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request[i].number_of_ibs = 2;
+ ibs_request[i].ibs = ib_info;
+ ibs_request[i].resources = bo_list;
+ ibs_request[i].fence_info.handle = NULL;
+ }
+
+ r = amdgpu_cs_submit(context_handle, 0,ibs_request, ib_cs_num);
+
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (i = 0; i < ib_cs_num; i++) {
+ fence_status[i].context = context_handle;
+ fence_status[i].ip_type = AMDGPU_HW_IP_GFX;
+ fence_status[i].fence = ibs_request[i].seq_no;
+ }
+
+ r = amdgpu_cs_wait_fences(fence_status, ib_cs_num, wait_all,
+ AMDGPU_TIMEOUT_INFINITE,
+ &expired, NULL);
+ 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(ib_result_ce_handle, va_handle_ce,
+ ib_result_ce_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_command_submission_multi_fence(void)
+{
+ amdgpu_command_submission_multi_fence_wait_all(true);
+ amdgpu_command_submission_multi_fence_wait_all(false);
+}
+
static void amdgpu_userptr_test(void)
{
int i, r, j;
@@ -1175,15 +1629,28 @@ static void amdgpu_userptr_test(void)
handle = buf_handle;
j = i = 0;
- pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
- SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
+
+ if (family_id == AMDGPU_FAMILY_SI)
+ pm4[i++] = SDMA_PACKET_SI(SDMA_OPCODE_WRITE, 0, 0, 0,
+ sdma_write_length);
+ else
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
+ SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
pm4[i++] = 0xffffffff & bo_mc;
pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
- pm4[i++] = sdma_write_length;
+ if (family_id >= AMDGPU_FAMILY_AI)
+ pm4[i++] = sdma_write_length - 1;
+ else if (family_id != AMDGPU_FAMILY_SI)
+ pm4[i++] = sdma_write_length;
while (j++ < sdma_write_length)
pm4[i++] = 0xdeadbeaf;
+ if (!fork()) {
+ pm4[0] = 0x0;
+ exit(0);
+ }
+
amdgpu_test_exec_cs_helper(context_handle,
AMDGPU_HW_IP_DMA, 0,
i, pm4,
@@ -1207,4 +1674,212 @@ static void amdgpu_userptr_test(void)
r = amdgpu_cs_ctx_free(context_handle);
CU_ASSERT_EQUAL(r, 0);
+
+ wait(NULL);
+}
+
+static void amdgpu_sync_dependency_test(void)
+{
+ amdgpu_context_handle context_handle[2];
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, j, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ static uint32_t *ptr;
+ uint64_t seq_no;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 8192, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ i = 0;
+
+ memcpy(ptr + CODE_OFFSET , shader_bin, sizeof(shader_bin));
+
+ /* Dispatch minimal init config and verify it's executed */
+ ptr[i++] = PACKET3(PKT3_CONTEXT_CONTROL, 1);
+ ptr[i++] = 0x80000000;
+ ptr[i++] = 0x80000000;
+
+ ptr[i++] = PACKET3(PKT3_CLEAR_STATE, 0);
+ ptr[i++] = 0x80000000;
+
+
+ /* Program compute regs */
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START;
+ ptr[i++] = (ib_result_mc_address + CODE_OFFSET * 4) >> 8;
+ ptr[i++] = (ib_result_mc_address + CODE_OFFSET * 4) >> 40;
+
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_PGM_RSRC1 - PACKET3_SET_SH_REG_START;
+ /*
+ * 002c0040 COMPUTE_PGM_RSRC1 <- VGPRS = 0
+ SGPRS = 1
+ PRIORITY = 0
+ FLOAT_MODE = 192 (0xc0)
+ PRIV = 0
+ DX10_CLAMP = 1
+ DEBUG_MODE = 0
+ IEEE_MODE = 0
+ BULKY = 0
+ CDBG_USER = 0
+ *
+ */
+ ptr[i++] = 0x002c0040;
+
+
+ /*
+ * 00000010 COMPUTE_PGM_RSRC2 <- SCRATCH_EN = 0
+ USER_SGPR = 8
+ TRAP_PRESENT = 0
+ TGID_X_EN = 0
+ TGID_Y_EN = 0
+ TGID_Z_EN = 0
+ TG_SIZE_EN = 0
+ TIDIG_COMP_CNT = 0
+ EXCP_EN_MSB = 0
+ LDS_SIZE = 0
+ EXCP_EN = 0
+ *
+ */
+ ptr[i++] = 0x00000010;
+
+
+/*
+ * 00000100 COMPUTE_TMPRING_SIZE <- WAVES = 256 (0x100)
+ WAVESIZE = 0
+ *
+ */
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1);
+ ptr[i++] = mmCOMPUTE_TMPRING_SIZE - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0x00000100;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2);
+ ptr[i++] = mmCOMPUTE_USER_DATA_0 - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0xffffffff & (ib_result_mc_address + DATA_OFFSET * 4);
+ ptr[i++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1);
+ ptr[i++] = mmCOMPUTE_RESOURCE_LIMITS - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 0;
+
+ ptr[i++] = PACKET3(PKT3_SET_SH_REG, 3);
+ ptr[i++] = mmCOMPUTE_NUM_THREAD_X - PACKET3_SET_SH_REG_START;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+
+
+ /* Dispatch */
+ ptr[i++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3);
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 1;
+ ptr[i++] = 0x00000045; /* DISPATCH DIRECT field */
+
+
+ while (i & 7)
+ ptr[i++] = 0xffff1000; /* type3 nop packet */
+
+ 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_GFX;
+ 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[1], 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+ seq_no = ibs_request.seq_no;
+
+
+
+ /* Prepare second command with dependency on the first */
+ j = i;
+ ptr[i++] = PACKET3(PACKET3_WRITE_DATA, 3);
+ ptr[i++] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
+ ptr[i++] = 0xfffffffc & (ib_result_mc_address + DATA_OFFSET * 4);
+ ptr[i++] = (0xffffffff00000000 & (ib_result_mc_address + DATA_OFFSET * 4)) >> 32;
+ ptr[i++] = 99;
+
+ while (i & 7)
+ ptr[i++] = 0xffff1000; /* type3 nop packet */
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address + j * 4;
+ ib_info.size = i - j;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ 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;
+
+ ibs_request.number_of_dependencies = 1;
+
+ ibs_request.dependencies = calloc(1, sizeof(*ibs_request.dependencies));
+ ibs_request.dependencies[0].context = context_handle[1];
+ ibs_request.dependencies[0].ip_instance = 0;
+ ibs_request.dependencies[0].ring = 0;
+ ibs_request.dependencies[0].fence = seq_no;
+
+
+ r = amdgpu_cs_submit(context_handle[0], 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle[0];
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ 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);
+
+ /* Expect the second command to wait for shader to complete */
+ CU_ASSERT_EQUAL(ptr[DATA_OFFSET], 99);
+
+ 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_cs_ctx_free(context_handle[0]);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_cs_ctx_free(context_handle[1]);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free(ibs_request.dependencies);
}
diff --git a/tests/amdgpu/bo_tests.c b/tests/amdgpu/bo_tests.c
index 74b5e77b..7cff4cf7 100644
--- a/tests/amdgpu/bo_tests.c
+++ b/tests/amdgpu/bo_tests.c
@@ -21,16 +21,13 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include "CUnit/Basic.h"
#include "amdgpu_test.h"
#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
#define BUFFER_SIZE (4*1024)
#define BUFFER_ALIGN (4*1024)
@@ -46,13 +43,17 @@ static amdgpu_va_handle va_handle;
static void amdgpu_bo_export_import(void);
static void amdgpu_bo_metadata(void);
static void amdgpu_bo_map_unmap(void);
+static void amdgpu_memory_alloc(void);
+static void amdgpu_mem_fail_alloc(void);
+static void amdgpu_bo_find_by_cpu_mapping(void);
CU_TestInfo bo_tests[] = {
{ "Export/Import", amdgpu_bo_export_import },
-#if 0
{ "Metadata", amdgpu_bo_metadata },
-#endif
{ "CPU map/unmap", amdgpu_bo_map_unmap },
+ { "Memory alloc Test", amdgpu_memory_alloc },
+ { "Memory fail alloc Test", amdgpu_mem_fail_alloc },
+ { "Find bo by CPU mapping", amdgpu_bo_find_by_cpu_mapping },
CU_TEST_INFO_NULL,
};
@@ -195,3 +196,123 @@ static void amdgpu_bo_map_unmap(void)
r = amdgpu_bo_cpu_unmap(buffer_handle);
CU_ASSERT_EQUAL(r, 0);
}
+
+static void amdgpu_memory_alloc(void)
+{
+ amdgpu_bo_handle bo;
+ amdgpu_va_handle va_handle;
+ uint64_t bo_mc;
+ int r;
+
+ /* Test visible VRAM */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test invisible VRAM */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GART Cacheable */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ 0, &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GART USWC */
+ bo = gpu_mem_alloc(device_handle,
+ 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_CREATE_CPU_GTT_USWC,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GDS */
+ bo = gpu_mem_alloc(device_handle, 1024, 0,
+ AMDGPU_GEM_DOMAIN_GDS, 0,
+ NULL, NULL);
+ r = gpu_mem_free(bo, NULL, 0, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test GWS */
+ bo = gpu_mem_alloc(device_handle, 1, 0,
+ AMDGPU_GEM_DOMAIN_GWS, 0,
+ NULL, NULL);
+ r = gpu_mem_free(bo, NULL, 0, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test OA */
+ bo = gpu_mem_alloc(device_handle, 1, 0,
+ AMDGPU_GEM_DOMAIN_OA, 0,
+ NULL, NULL);
+ r = gpu_mem_free(bo, NULL, 0, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_mem_fail_alloc(void)
+{
+ amdgpu_bo_handle bo;
+ int r;
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+
+ /* Test impossible mem allocation, 1TB */
+ req.alloc_size = 0xE8D4A51000;
+ req.phys_alignment = 4096;
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;
+ req.flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, -ENOMEM);
+
+ if (!r) {
+ r = amdgpu_bo_free(bo);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+}
+
+static void amdgpu_bo_find_by_cpu_mapping(void)
+{
+ amdgpu_bo_handle bo_handle, find_bo_handle;
+ amdgpu_va_handle va_handle;
+ void *bo_cpu;
+ uint64_t bo_mc_address;
+ uint64_t offset;
+ int r;
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &bo_handle, &bo_cpu,
+ &bo_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_find_bo_by_cpu_mapping(device_handle,
+ bo_cpu,
+ 4096,
+ &find_bo_handle,
+ &offset);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(offset, 0);
+ CU_ASSERT_EQUAL(bo_handle->handle, find_bo_handle->handle);
+
+ atomic_dec(&find_bo_handle->refcount, 1);
+ r = amdgpu_bo_unmap_and_free(bo_handle, va_handle,
+ bo_mc_address, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+}
diff --git a/tests/amdgpu/cs_tests.c b/tests/amdgpu/cs_tests.c
index 82c55aa8..7ad0f0dc 100644
--- a/tests/amdgpu/cs_tests.c
+++ b/tests/amdgpu/cs_tests.c
@@ -21,10 +21,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include "CUnit/Basic.h"
@@ -32,7 +28,7 @@
#include "util_math.h"
#include "amdgpu_test.h"
-#include "uvd_messages.h"
+#include "decode_messages.h"
#include "amdgpu_drm.h"
#include "amdgpu_internal.h"
@@ -66,6 +62,26 @@ CU_TestInfo cs_tests[] = {
CU_TEST_INFO_NULL,
};
+CU_BOOL suite_cs_tests_enable(void)
+{
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+
+ if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI) {
+ printf("\n\nThe ASIC NOT support UVD, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ return CU_TRUE;
+}
+
int suite_cs_tests_init(void)
{
amdgpu_bo_handle ib_result_handle;
@@ -175,11 +191,11 @@ static int submit(unsigned ndw, unsigned ip)
static void uvd_cmd(uint64_t addr, unsigned cmd, int *idx)
{
- ib_cpu[(*idx)++] = 0x3BC4;
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC4 : 0x81C4;
ib_cpu[(*idx)++] = addr;
- ib_cpu[(*idx)++] = 0x3BC5;
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC5 : 0x81C5;
ib_cpu[(*idx)++] = addr >> 32;
- ib_cpu[(*idx)++] = 0x3BC3;
+ ib_cpu[(*idx)++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC3 : 0x81C3;
ib_cpu[(*idx)++] = cmd << 1;
}
@@ -211,10 +227,13 @@ static void amdgpu_cs_uvd_create(void)
CU_ASSERT_EQUAL(r, 0);
memcpy(msg, uvd_create_msg, sizeof(uvd_create_msg));
+
if (family_id >= AMDGPU_FAMILY_VI) {
((uint8_t*)msg)[0x10] = 7;
- /* chip polaris 10/11 */
- if (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A) {
+ /* chip beyond polaris 10/11 */
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
/* dpb size */
((uint8_t*)msg)[0x28] = 0x00;
((uint8_t*)msg)[0x29] = 0x94;
@@ -250,7 +269,7 @@ static void amdgpu_cs_uvd_create(void)
static void amdgpu_cs_uvd_decode(void)
{
- const unsigned dpb_size = 15923584, ctx_size = 5287680, dt_size = 737280;
+ const unsigned dpb_size = 15923584, dt_size = 737280;
uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, ctx_addr, dt_addr, it_addr;
struct amdgpu_bo_alloc_request req = {0};
amdgpu_bo_handle buf_handle;
@@ -286,14 +305,18 @@ static void amdgpu_cs_uvd_decode(void)
r = amdgpu_bo_cpu_map(buf_handle, (void **)&ptr);
CU_ASSERT_EQUAL(r, 0);
- memcpy(ptr, uvd_decode_msg, sizeof(uvd_create_msg));
+ memcpy(ptr, uvd_decode_msg, sizeof(uvd_decode_msg));
+ memcpy(ptr + sizeof(uvd_decode_msg), avc_decode_msg, sizeof(avc_decode_msg));
+
if (family_id >= AMDGPU_FAMILY_VI) {
ptr[0x10] = 7;
ptr[0x98] = 0x00;
ptr[0x99] = 0x02;
- /* chip polaris10/11 */
- if (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A) {
- /*dpb size */
+ /* chip beyond polaris10/11 */
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
+ /* dpb size */
ptr[0x24] = 0x00;
ptr[0x25] = 0x94;
ptr[0x26] = 0x6B;
@@ -335,9 +358,12 @@ static void amdgpu_cs_uvd_decode(void)
bs_addr = fb_addr + 4*1024;
dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
- if ((family_id >= AMDGPU_FAMILY_VI) &&
- (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A)) {
- ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
+ if (family_id >= AMDGPU_FAMILY_VI) {
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64)) {
+ ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
+ }
}
dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
@@ -348,12 +374,16 @@ static void amdgpu_cs_uvd_decode(void)
uvd_cmd(dt_addr, 0x2, &i);
uvd_cmd(fb_addr, 0x3, &i);
uvd_cmd(bs_addr, 0x100, &i);
+
if (family_id >= AMDGPU_FAMILY_VI) {
uvd_cmd(it_addr, 0x204, &i);
- if (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A)
+ if ((family_id == AMDGPU_FAMILY_AI) ||
+ (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
+ chip_id == chip_rev+0x64))
uvd_cmd(ctx_addr, 0x206, &i);
-}
- ib_cpu[i++] = 0x3BC6;
+ }
+
+ ib_cpu[i++] = (family_id < AMDGPU_FAMILY_AI) ? 0x3BC6 : 0x81C6;
ib_cpu[i++] = 0x1;
for (; i % 16; ++i)
ib_cpu[i] = 0x80000000;
@@ -364,7 +394,7 @@ static void amdgpu_cs_uvd_decode(void)
/* TODO: use a real CRC32 */
for (i = 0, sum = 0; i < dt_size; ++i)
sum += ptr[i];
- CU_ASSERT_EQUAL(sum, 0x20345d8);
+ CU_ASSERT_EQUAL(sum, SUM_DECODE);
r = amdgpu_bo_cpu_unmap(buf_handle);
CU_ASSERT_EQUAL(r, 0);
diff --git a/tests/amdgpu/deadlock_tests.c b/tests/amdgpu/deadlock_tests.c
new file mode 100644
index 00000000..a6c2635d
--- /dev/null
+++ b/tests/amdgpu/deadlock_tests.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright 2017 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#include <pthread.h>
+
+
+/*
+ * This defines the delay in MS after which memory location designated for
+ * compression against reference value is written to, unblocking command
+ * processor
+ */
+#define WRITE_MEM_ADDRESS_DELAY_MS 100
+
+#define PACKET_TYPE3 3
+
+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
+ (((op) & 0xFF) << 8) | \
+ ((n) & 0x3FFF) << 16)
+
+#define PACKET3_WAIT_REG_MEM 0x3C
+#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0)
+ /* 0 - always
+ * 1 - <
+ * 2 - <=
+ * 3 - ==
+ * 4 - !=
+ * 5 - >=
+ * 6 - >
+ */
+#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4)
+ /* 0 - reg
+ * 1 - mem
+ */
+#define WAIT_REG_MEM_OPERATION(x) ((x) << 6)
+ /* 0 - wait_reg_mem
+ * 1 - wr_wait_wr_reg
+ */
+#define WAIT_REG_MEM_ENGINE(x) ((x) << 8)
+ /* 0 - me
+ * 1 - pfp
+ */
+
+#define PACKET3_WRITE_DATA 0x37
+#define WRITE_DATA_DST_SEL(x) ((x) << 8)
+ /* 0 - register
+ * 1 - memory (sync - via GRBM)
+ * 2 - gl2
+ * 3 - gds
+ * 4 - reserved
+ * 5 - memory (async - direct)
+ */
+#define WR_ONE_ADDR (1 << 16)
+#define WR_CONFIRM (1 << 20)
+#define WRITE_DATA_CACHE_POLICY(x) ((x) << 25)
+ /* 0 - LRU
+ * 1 - Stream
+ */
+#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
+ /* 0 - me
+ * 1 - pfp
+ * 2 - ce
+ */
+
+#define mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x54f
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static pthread_t stress_thread;
+static uint32_t *ptr;
+
+int use_uc_mtype = 0;
+
+static void amdgpu_deadlock_helper(unsigned ip_type);
+static void amdgpu_deadlock_gfx(void);
+static void amdgpu_deadlock_compute(void);
+static void amdgpu_illegal_reg_access();
+static void amdgpu_illegal_mem_access();
+
+CU_BOOL suite_deadlock_tests_enable(void)
+{
+ CU_BOOL enable = CU_TRUE;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ /*
+ * Only enable for ASICs supporting GPU reset and for which it's enabled
+ * by default (currently GFX8/9 dGPUS)
+ */
+ if (device_handle->info.family_id != AMDGPU_FAMILY_VI &&
+ device_handle->info.family_id != AMDGPU_FAMILY_AI &&
+ device_handle->info.family_id != AMDGPU_FAMILY_CI) {
+ printf("\n\nGPU reset is not enabled for the ASIC, deadlock suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if (device_handle->info.family_id >= AMDGPU_FAMILY_AI)
+ use_uc_mtype = 1;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ return enable;
+}
+
+int suite_deadlock_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_deadlock_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+
+CU_TestInfo deadlock_tests[] = {
+ { "gfx ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_gfx },
+ { "compute ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_compute },
+ { "illegal reg access test", amdgpu_illegal_reg_access },
+ { "illegal mem access test (set amdgpu.vm_fault_stop=2)", amdgpu_illegal_mem_access },
+ CU_TEST_INFO_NULL,
+};
+
+static void *write_mem_address(void *data)
+{
+ int i;
+
+ /* useconds_t range is [0, 1,000,000] so use loop for waits > 1s */
+ for (i = 0; i < WRITE_MEM_ADDRESS_DELAY_MS; i++)
+ usleep(1000);
+
+ ptr[256] = 0x1;
+
+ return 0;
+}
+
+static void amdgpu_deadlock_gfx(void)
+{
+ amdgpu_deadlock_helper(AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_deadlock_compute(void)
+{
+ amdgpu_deadlock_helper(AMDGPU_HW_IP_COMPUTE);
+}
+
+static void amdgpu_deadlock_helper(unsigned ip_type)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+
+ r = pthread_create(&stress_thread, NULL, write_mem_address, NULL);
+ 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_raw(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, use_uc_mtype ? AMDGPU_VM_MTYPE_UC : 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+
+ ptr[0] = PACKET3(PACKET3_WAIT_REG_MEM, 5);
+ ptr[1] = (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
+ WAIT_REG_MEM_FUNCTION(4) | /* != */
+ WAIT_REG_MEM_ENGINE(0)); /* me */
+ ptr[2] = (ib_result_mc_address + 256*4) & 0xfffffffc;
+ ptr[3] = ((ib_result_mc_address + 256*4) >> 32) & 0xffffffff;
+ ptr[4] = 0x00000000; /* reference value */
+ ptr[5] = 0xffffffff; /* and mask */
+ ptr[6] = 0x00000004; /* poll interval */
+
+ for (i = 7; i < 16; ++i)
+ ptr[i] = 0xffff1000;
+
+
+ ptr[256] = 0x0; /* the memory we wait on to change */
+
+
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = ip_type;
+ 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;
+
+ for (i = 0; i < 200; i++) {
+ r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
+ CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1);
+
+ }
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = ip_type;
+ 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);
+
+ pthread_join(stress_thread, NULL);
+
+ 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_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void bad_access_helper(int reg_access)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map_raw(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+ i = 0;
+
+ ptr[i++] = PACKET3(PACKET3_WRITE_DATA, 3);
+ ptr[i++] = (reg_access ? WRITE_DATA_DST_SEL(0) : WRITE_DATA_DST_SEL(5))| WR_CONFIRM;
+ ptr[i++] = reg_access ? mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR : 0xdeadbee0;
+ ptr[i++] = 0;
+ ptr[i++] = 0xdeadbeef;
+
+ for (; i < 16; ++i)
+ ptr[i] = 0xffff1000;
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ 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 || r == -ECANCELED), 1);
+
+
+ memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
+ fence_status.context = context_handle;
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ 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_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_illegal_reg_access()
+{
+ bad_access_helper(1);
+}
+
+static void amdgpu_illegal_mem_access()
+{
+ bad_access_helper(0);
+}
diff --git a/tests/amdgpu/uvd_messages.h b/tests/amdgpu/decode_messages.h
index 00235cbb..bd6fe4b6 100644
--- a/tests/amdgpu/uvd_messages.h
+++ b/tests/amdgpu/decode_messages.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2017 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"),
@@ -21,8 +21,10 @@
*
*/
-#ifndef _UVD_MESSAGES_H_
-#define _UVD_MESSAGES_H_
+#ifndef _DECODE_MESSAGES_H_
+#define _DECODE_MESSAGES_H_
+
+#define SUM_DECODE 0x20345d8
static const uint8_t uvd_create_msg[] = {
0xe4,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
@@ -356,6 +358,9 @@ static const uint8_t uvd_decode_msg[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t avc_decode_msg[] = {
0x02,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x88,0x00,0x00,0x00,
0x01,0x00,0x00,0x01,0x00,0x03,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
@@ -810,4 +815,34 @@ static const uint8_t uvd_it_scaling_table[] = {
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
};
-#endif /* _UVD_MESSAGES_H_ */
+static const uint8_t vcn_dec_create_msg[] = {
+ 0x28,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x28,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,
+};
+
+static const uint8_t vcn_dec_decode_msg[] = {
+ 0x28,0x00,0x00,0x00,0x90,0x06,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
+ 0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xec,0x00,0x00,0x00,
+ 0x5c,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x94,0x6b,0x00,
+ 0x96,0x4e,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x50,0x00,
+ 0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,
+ 0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xc0,0x03,0x00,0x00,0x80,0x07,0x00,0x00,0x60,0x09,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint8_t vcn_dec_destroy_msg[] = {
+ 0x28,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
+};
+
+#endif /* _DECODE_MESSAGES_H_ */
diff --git a/tests/amdgpu/frame.h b/tests/amdgpu/frame.h
index 4c946c27..335401c1 100644
--- a/tests/amdgpu/frame.h
+++ b/tests/amdgpu/frame.h
@@ -24,7 +24,7 @@
#ifndef _frame_h_
#define _frame_h_
-const uint8_t frame[] = {
+static const uint8_t frame[] = {
0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
new file mode 100644
index 00000000..4c1237c6
--- /dev/null
+++ b/tests/amdgpu/meson.build
@@ -0,0 +1,34 @@
+# 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.
+
+if dep_cunit.found()
+ amdgpu_test = executable(
+ 'amdgpu_test',
+ files(
+ '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',
+ ),
+ dependencies : [dep_cunit, dep_threads],
+ include_directories : [inc_root, inc_drm, include_directories('../../amdgpu')],
+ link_with : [libdrm, libdrm_amdgpu],
+ install : with_install_tests,
+ )
+endif
diff --git a/tests/amdgpu/uvd_enc_tests.c b/tests/amdgpu/uvd_enc_tests.c
new file mode 100644
index 00000000..b4251bcf
--- /dev/null
+++ b/tests/amdgpu/uvd_enc_tests.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright 2017 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 <stdio.h>
+#include <inttypes.h>
+
+#include "CUnit/Basic.h"
+
+#include "util_math.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "frame.h"
+#include "uve_ib.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+
+struct amdgpu_uvd_enc_bo {
+ amdgpu_bo_handle handle;
+ amdgpu_va_handle va_handle;
+ uint64_t addr;
+ uint64_t size;
+ uint8_t *ptr;
+};
+
+struct amdgpu_uvd_enc {
+ unsigned width;
+ unsigned height;
+ struct amdgpu_uvd_enc_bo session;
+ struct amdgpu_uvd_enc_bo vbuf;
+ struct amdgpu_uvd_enc_bo bs;
+ struct amdgpu_uvd_enc_bo fb;
+ struct amdgpu_uvd_enc_bo cpb;
+};
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_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 struct amdgpu_uvd_enc enc;
+static amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static void amdgpu_cs_uvd_enc_create(void);
+static void amdgpu_cs_uvd_enc_session_init(void);
+static void amdgpu_cs_uvd_enc_encode(void);
+static void amdgpu_cs_uvd_enc_destroy(void);
+
+
+CU_TestInfo uvd_enc_tests[] = {
+ { "UVD ENC create", amdgpu_cs_uvd_enc_create },
+ { "UVD ENC session init", amdgpu_cs_uvd_enc_session_init },
+ { "UVD ENC encode", amdgpu_cs_uvd_enc_encode },
+ { "UVD ENC destroy", amdgpu_cs_uvd_enc_destroy },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_uvd_enc_tests_enable(void)
+{
+ int r;
+ struct drm_amdgpu_info_hw_ip info;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_UVD_ENC, 0, &info);
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ if (!info.available_rings)
+ printf("\n\nThe ASIC NOT support UVD ENC, suite disabled.\n");
+
+ return (r == 0 && (info.available_rings ? CU_TRUE : CU_FALSE));
+}
+
+
+int suite_uvd_enc_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = device_handle->info.family_id;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(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;
+
+ return CUE_SUCCESS;
+}
+
+int suite_uvd_enc_tests_clean(void)
+{
+ int r;
+
+ 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(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ 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;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ 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 = ip;
+ 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 alloc_resource(struct amdgpu_uvd_enc_bo *uvd_enc_bo,
+ unsigned size, unsigned domain)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ int r;
+
+ req.alloc_size = ALIGN(size, 4096);
+ req.preferred_heap = domain;
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ uvd_enc_bo->addr = va;
+ uvd_enc_bo->handle = buf_handle;
+ uvd_enc_bo->size = req.alloc_size;
+ uvd_enc_bo->va_handle = va_handle;
+ r = amdgpu_bo_cpu_map(uvd_enc_bo->handle, (void **)&uvd_enc_bo->ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(uvd_enc_bo->ptr, 0, size);
+ r = amdgpu_bo_cpu_unmap(uvd_enc_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void free_resource(struct amdgpu_uvd_enc_bo *uvd_enc_bo)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(uvd_enc_bo->handle, 0, uvd_enc_bo->size,
+ uvd_enc_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(uvd_enc_bo->va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(uvd_enc_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(uvd_enc_bo, 0, sizeof(*uvd_enc_bo));
+}
+
+static void amdgpu_cs_uvd_enc_create(void)
+{
+ enc.width = 160;
+ enc.height = 128;
+
+ num_resources = 0;
+ alloc_resource(&enc.session, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.session.handle;
+ resources[num_resources++] = ib_handle;
+}
+
+static void check_result(struct amdgpu_uvd_enc *enc)
+{
+ uint64_t sum;
+ uint32_t s = 175602;
+ uint32_t *ptr, size;
+ int j, r;
+
+ r = amdgpu_bo_cpu_map(enc->fb.handle, (void **)&enc->fb.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr = (uint32_t *)enc->fb.ptr;
+ size = ptr[6];
+ r = amdgpu_bo_cpu_unmap(enc->fb.handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_map(enc->bs.handle, (void **)&enc->bs.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ for (j = 0, sum = 0; j < size; ++j)
+ sum += enc->bs.ptr[j];
+ CU_ASSERT_EQUAL(sum, s);
+ r = amdgpu_bo_cpu_unmap(enc->bs.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+}
+
+static void amdgpu_cs_uvd_enc_session_init(void)
+{
+ int len, r;
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0x000000d8;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_op_init, sizeof(uve_op_init));
+ len += sizeof(uve_op_init) / 4;
+
+ memcpy((ib_cpu + len), uve_session_init, sizeof(uve_session_init));
+ len += sizeof(uve_session_init) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_ctrl, sizeof(uve_layer_ctrl));
+ len += sizeof(uve_layer_ctrl) / 4;
+
+ memcpy((ib_cpu + len), uve_slice_ctrl, sizeof(uve_slice_ctrl));
+ len += sizeof(uve_slice_ctrl) / 4;
+
+ memcpy((ib_cpu + len), uve_spec_misc, sizeof(uve_spec_misc));
+ len += sizeof(uve_spec_misc) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_session_init, sizeof(uve_rc_session_init));
+ len += sizeof(uve_rc_session_init) / 4;
+
+ memcpy((ib_cpu + len), uve_deblocking_filter, sizeof(uve_deblocking_filter));
+ len += sizeof(uve_deblocking_filter) / 4;
+
+ memcpy((ib_cpu + len), uve_quality_params, sizeof(uve_quality_params));
+ len += sizeof(uve_quality_params) / 4;
+
+ memcpy((ib_cpu + len), uve_op_init_rc, sizeof(uve_op_init_rc));
+ len += sizeof(uve_op_init_rc) / 4;
+
+ memcpy((ib_cpu + len), uve_op_init_rc_vbv_level, sizeof(uve_op_init_rc_vbv_level));
+ len += sizeof(uve_op_init_rc_vbv_level) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_uvd_enc_encode(void)
+{
+ int len, r, i;
+ uint64_t luma_offset, chroma_offset;
+ uint32_t vbuf_size, bs_size = 0x003f4800, cpb_size;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5;
+ cpb_size = vbuf_size * 10;
+
+
+ num_resources = 0;
+ alloc_resource(&enc.fb, 4096, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.fb.handle;
+ alloc_resource(&enc.bs, bs_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.bs.handle;
+ alloc_resource(&enc.vbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.vbuf.handle;
+ alloc_resource(&enc.cpb, cpb_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.cpb.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(enc.vbuf.ptr, 0, vbuf_size);
+ for (i = 0; i < enc.height; ++i) {
+ memcpy(enc.vbuf.ptr, (frame + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+ for (i = 0; i < enc.height / 2; ++i) {
+ memcpy(enc.vbuf.ptr, ((frame + enc.height * enc.width) + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+
+ r = amdgpu_bo_cpu_unmap(enc.vbuf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0x000005e0;
+ ib_cpu[len++] = 0x00000001;
+ ib_cpu[len++] = 0x00000001;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_1, sizeof(uve_nalu_buffer_1));
+ len += sizeof(uve_nalu_buffer_1) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_2, sizeof(uve_nalu_buffer_2));
+ len += sizeof(uve_nalu_buffer_2) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_3, sizeof(uve_nalu_buffer_3));
+ len += sizeof(uve_nalu_buffer_3) / 4;
+
+ memcpy((ib_cpu + len), uve_nalu_buffer_4, sizeof(uve_nalu_buffer_4));
+ len += sizeof(uve_nalu_buffer_4) / 4;
+
+ memcpy((ib_cpu + len), uve_slice_header, sizeof(uve_slice_header));
+ len += sizeof(uve_slice_header) / 4;
+
+ ib_cpu[len++] = 0x00000254;
+ ib_cpu[len++] = 0x00000010;
+ ib_cpu[len++] = enc.cpb.addr >> 32;
+ ib_cpu[len++] = enc.cpb.addr;
+ memcpy((ib_cpu + len), uve_ctx_buffer, sizeof(uve_ctx_buffer));
+ len += sizeof(uve_ctx_buffer) / 4;
+
+ memcpy((ib_cpu + len), uve_bitstream_buffer, sizeof(uve_bitstream_buffer));
+ len += sizeof(uve_bitstream_buffer) / 4;
+ ib_cpu[len++] = 0x00000000;
+ ib_cpu[len++] = enc.bs.addr >> 32;
+ ib_cpu[len++] = enc.bs.addr;
+ ib_cpu[len++] = 0x003f4800;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_feedback_buffer, sizeof(uve_feedback_buffer));
+ len += sizeof(uve_feedback_buffer) / 4;
+ ib_cpu[len++] = enc.fb.addr >> 32;
+ ib_cpu[len++] = enc.fb.addr;
+ ib_cpu[len++] = 0x00000010;
+ ib_cpu[len++] = 0x00000028;
+
+ memcpy((ib_cpu + len), uve_feedback_buffer_additional, sizeof(uve_feedback_buffer_additional));
+ len += sizeof(uve_feedback_buffer_additional) / 4;
+
+ memcpy((ib_cpu + len), uve_intra_refresh, sizeof(uve_intra_refresh));
+ len += sizeof(uve_intra_refresh) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_select, sizeof(uve_layer_select));
+ len += sizeof(uve_layer_select) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_layer_init, sizeof(uve_rc_layer_init));
+ len += sizeof(uve_rc_layer_init) / 4;
+
+ memcpy((ib_cpu + len), uve_layer_select, sizeof(uve_layer_select));
+ len += sizeof(uve_layer_select) / 4;
+
+ memcpy((ib_cpu + len), uve_rc_per_pic, sizeof(uve_rc_per_pic));
+ len += sizeof(uve_rc_per_pic) / 4;
+
+ unsigned luma_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16);
+ luma_offset = enc.vbuf.addr;
+ chroma_offset = luma_offset + luma_size;
+ ib_cpu[len++] = 0x00000054;
+ ib_cpu[len++] = 0x0000000c;
+ ib_cpu[len++] = 0x00000002;
+ ib_cpu[len++] = 0x003f4800;
+ ib_cpu[len++] = luma_offset >> 32;
+ ib_cpu[len++] = luma_offset;
+ ib_cpu[len++] = chroma_offset >> 32;
+ ib_cpu[len++] = chroma_offset;
+ memcpy((ib_cpu + len), uve_encode_param, sizeof(uve_encode_param));
+ ib_cpu[len] = ALIGN(enc.width, align);
+ ib_cpu[len + 1] = ALIGN(enc.width, align);
+ len += sizeof(uve_encode_param) / 4;
+
+ memcpy((ib_cpu + len), uve_op_speed_enc_mode, sizeof(uve_op_speed_enc_mode));
+ len += sizeof(uve_op_speed_enc_mode) / 4;
+
+ memcpy((ib_cpu + len), uve_op_encode, sizeof(uve_op_encode));
+ len += sizeof(uve_op_encode) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ check_result(&enc);
+
+ free_resource(&enc.fb);
+ free_resource(&enc.bs);
+ free_resource(&enc.vbuf);
+ free_resource(&enc.cpb);
+}
+
+static void amdgpu_cs_uvd_enc_destroy(void)
+{
+ int len, r;
+
+ num_resources = 0;
+ resources[num_resources++] = ib_handle;
+
+ len = 0;
+ memcpy((ib_cpu + len), uve_session_info, sizeof(uve_session_info));
+ len += sizeof(uve_session_info) / 4;
+ ib_cpu[len++] = enc.session.addr >> 32;
+ ib_cpu[len++] = enc.session.addr;
+
+ memcpy((ib_cpu + len), uve_task_info, sizeof(uve_task_info));
+ len += sizeof(uve_task_info) / 4;
+ ib_cpu[len++] = 0xffffffff;
+ ib_cpu[len++] = 0x00000002;
+ ib_cpu[len++] = 0x00000000;
+
+ memcpy((ib_cpu + len), uve_op_close, sizeof(uve_op_close));
+ len += sizeof(uve_op_close) / 4;
+
+ r = submit(len, AMDGPU_HW_IP_UVD_ENC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&enc.session);
+}
diff --git a/tests/amdgpu/uve_ib.h b/tests/amdgpu/uve_ib.h
new file mode 100644
index 00000000..cb72be22
--- /dev/null
+++ b/tests/amdgpu/uve_ib.h
@@ -0,0 +1,527 @@
+/*
+ * Copyright 2017 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 _uve_ib_h_
+#define _uve_ib_h_
+
+static const uint32_t uve_session_info[] = {
+ 0x00000018,
+ 0x00000001,
+ 0x00000000,
+ 0x00010000,
+};
+
+static const uint32_t uve_task_info[] = {
+ 0x00000014,
+ 0x00000002,
+};
+
+static const uint32_t uve_session_init[] = {
+ 0x00000020,
+ 0x00000003,
+ 0x000000c0,
+ 0x00000080,
+ 0x00000020,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_layer_ctrl[] = {
+ 0x00000010,
+ 0x00000004,
+ 0x00000001,
+ 0x00000001,
+};
+
+static const uint32_t uve_layer_select[] = {
+ 0x0000000c,
+ 0x00000005,
+ 0x00000000,
+};
+
+static const uint32_t uve_slice_ctrl[] = {
+ 0x00000014,
+ 0x00000006,
+ 0x00000000,
+ 0x00000006,
+ 0x00000006,
+};
+
+static const uint32_t uve_spec_misc[] = {
+ 0x00000024,
+ 0x00000007,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+ 0x00000001,
+};
+
+static const uint32_t uve_rc_session_init[] = {
+ 0x00000010,
+ 0x00000008,
+ 0x00000000,
+ 0x00000040,
+};
+
+static const uint32_t uve_rc_layer_init[] = {
+ 0x00000028,
+ 0x00000009,
+ 0x001e8480,
+ 0x001e8480,
+ 0x0000001e,
+ 0x00000001,
+ 0x0001046a,
+ 0x0001046a,
+ 0x0001046a,
+ 0xaaaaaaaa,
+};
+
+static const uint32_t uve_deblocking_filter[] = {
+ 0x00000020,
+ 0x0000000e,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_quality_params[] = {
+ 0x00000014,
+ 0x0000000d,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_feedback_buffer[] = {
+ 0x0000001c,
+ 0x00000012,
+ 0x00000000,
+};
+
+static const uint32_t uve_feedback_buffer_additional[] = {
+ 0x00000108,
+ 0x00000014,
+ 0x00000001,
+ 0x00000010,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_nalu_buffer_1[] = {
+ 0x00000018,
+ 0x00000013,
+ 0x00000001,
+ 0x00000007,
+ 0x00000001,
+ 0x46011000,
+};
+
+static const uint32_t uve_nalu_buffer_2[] = {
+ 0x0000002c,
+ 0x00000013,
+ 0x00000002,
+ 0x0000001b,
+ 0x00000001,
+ 0x40010c01,
+ 0xffff0160,
+ 0x00000300,
+ 0xb0000003,
+ 0x00000300,
+ 0x962c0900,
+};
+
+static const uint32_t uve_nalu_buffer_3[] = {
+ 0x00000034,
+ 0x00000013,
+ 0x00000003,
+ 0x00000023,
+ 0x00000001,
+ 0x42010101,
+ 0x60000003,
+ 0x00b00000,
+ 0x03000003,
+ 0x0096a018,
+ 0x2020708f,
+ 0xcb924295,
+ 0x12e08000,
+};
+
+static const uint32_t uve_nalu_buffer_4[] = {
+ 0x0000001c,
+ 0x00000013,
+ 0x00000004,
+ 0x0000000b,
+ 0x00000001,
+ 0x4401e0f1,
+ 0x80992000,
+};
+
+static const uint32_t uve_slice_header[] = {
+ 0x000000c8,
+ 0x0000000b,
+ 0x28010000,
+ 0x40000000,
+ 0x60000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000002,
+ 0x00000010,
+ 0x00000003,
+ 0x00000000,
+ 0x00000002,
+ 0x00000002,
+ 0x00000004,
+ 0x00000000,
+ 0x00000001,
+ 0x00000000,
+ 0x00000002,
+ 0x00000003,
+ 0x00000005,
+ 0x00000000,
+ 0x00000002,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_encode_param[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xffffffff,
+ 0x00000001,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_intra_refresh[] = {
+ 0x00000014,
+ 0x0000000f,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+};
+
+static const uint32_t uve_ctx_buffer[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x000000a0,
+ 0x000000a0,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+static const uint32_t uve_bitstream_buffer[] = {
+ 0x0000001c,
+ 0x00000011,
+};
+
+static const uint32_t uve_rc_per_pic[] = {
+ 0x00000024,
+ 0x0000000a,
+ 0x0000001a,
+ 0x00000000,
+ 0x00000033,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+};
+
+static const uint32_t uve_op_init[] = {
+ 0x00000008,
+ 0x08000001,
+};
+
+static const uint32_t uve_op_close[] = {
+ 0x00000008,
+ 0x08000002,
+};
+
+static const uint32_t uve_op_encode[] = {
+ 0x00000008,
+ 0x08000003,
+};
+
+static const uint32_t uve_op_init_rc[] = {
+ 0x00000008,
+ 0x08000004,
+};
+
+static const uint32_t uve_op_init_rc_vbv_level[] = {
+ 0x00000008,
+ 0x08000005,
+};
+
+static const uint32_t uve_op_speed_enc_mode[] = {
+ 0x00000008,
+ 0x08000006,
+};
+
+static const uint32_t uve_op_balance_enc_mode[] = {
+ 0x00000008,
+ 0x08000007,
+};
+
+static const uint32_t uve_op_quality_enc_mode[] = {
+ 0x00000008,
+ 0x08000008,
+};
+#endif /*_uve_ib_h*/
diff --git a/tests/amdgpu/vce_ib.h b/tests/amdgpu/vce_ib.h
index 80ab1795..f3108a04 100644
--- a/tests/amdgpu/vce_ib.h
+++ b/tests/amdgpu/vce_ib.h
@@ -315,4 +315,21 @@ static const uint32_t vce_destroy[] = {
0x00000008,
0x02000001,
};
+
+static const uint32_t vce_mv_buffer[] = {
+ 0x00000038,
+ 0x0500000d,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
#endif /*_vce_ib_h*/
diff --git a/tests/amdgpu/vce_tests.c b/tests/amdgpu/vce_tests.c
index de63aa15..b9e15ee9 100644
--- a/tests/amdgpu/vce_tests.c
+++ b/tests/amdgpu/vce_tests.c
@@ -21,10 +21,6 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include <inttypes.h>
@@ -41,6 +37,7 @@
#define IB_SIZE 4096
#define MAX_RESOURCES 16
+#define FW_53_0_03 ((53 << 24) | (0 << 16) | (03 << 8))
struct amdgpu_vce_bo {
amdgpu_bo_handle handle;
@@ -59,6 +56,9 @@ struct amdgpu_vce_encode {
struct amdgpu_vce_bo cpb;
unsigned ib_len;
bool two_instance;
+ struct amdgpu_vce_bo mvrefbuf;
+ struct amdgpu_vce_bo mvb;
+ unsigned mvbuf_size;
};
static amdgpu_device_handle device_handle;
@@ -66,6 +66,10 @@ static uint32_t major_version;
static uint32_t minor_version;
static uint32_t family_id;
static uint32_t vce_harvest_config;
+static uint32_t chip_rev;
+static uint32_t chip_id;
+static uint32_t ids_flags;
+static bool is_mv_supported = true;
static amdgpu_context_handle context_handle;
static amdgpu_bo_handle ib_handle;
@@ -79,15 +83,61 @@ static unsigned num_resources;
static void amdgpu_cs_vce_create(void);
static void amdgpu_cs_vce_encode(void);
+static void amdgpu_cs_vce_encode_mv(void);
static void amdgpu_cs_vce_destroy(void);
CU_TestInfo vce_tests[] = {
{ "VCE create", amdgpu_cs_vce_create },
{ "VCE encode", amdgpu_cs_vce_encode },
+ { "VCE MV dump", amdgpu_cs_vce_encode_mv },
{ "VCE destroy", amdgpu_cs_vce_destroy },
CU_TEST_INFO_NULL,
};
+CU_BOOL suite_vce_tests_enable(void)
+{
+ uint32_t version, feature;
+ CU_BOOL ret_mv = CU_FALSE;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+ chip_rev = device_handle->info.chip_rev;
+ chip_id = device_handle->info.chip_external_rev;
+ ids_flags = device_handle->info.ids_flags;
+
+ amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0,
+ 0, &version, &feature);
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI) {
+ printf("\n\nThe ASIC NOT support VCE, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ if (!(chip_id == (chip_rev + 0x3C) || /* FIJI */
+ chip_id == (chip_rev + 0x50) || /* Polaris 10*/
+ chip_id == (chip_rev + 0x5A) || /* Polaris 11*/
+ chip_id == (chip_rev + 0x64) || /* Polaris 12*/
+ (family_id >= AMDGPU_FAMILY_AI && !ids_flags))) /* dGPU > Polaris */
+ printf("\n\nThe ASIC NOT support VCE MV, suite disabled\n");
+ else if (FW_53_0_03 > version)
+ printf("\n\nThe ASIC FW version NOT support VCE MV, suite disabled\n");
+ else
+ ret_mv = CU_TRUE;
+
+ if (ret_mv == CU_FALSE) {
+ amdgpu_set_test_active("VCE Tests", "VCE MV dump", ret_mv);
+ is_mv_supported = false;
+ }
+
+ return CU_TRUE;
+}
+
int suite_vce_tests_init(void)
{
int r;
@@ -234,6 +284,7 @@ static void free_resource(struct amdgpu_vce_bo *vce_bo)
static void amdgpu_cs_vce_create(void)
{
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
int len, r;
enc.width = vce_create[6];
@@ -250,6 +301,14 @@ static void amdgpu_cs_vce_create(void)
memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
len += sizeof(vce_taskinfo) / 4;
memcpy((ib_cpu + len), vce_create, sizeof(vce_create));
+ ib_cpu[len + 8] = ALIGN(enc.width, align);
+ ib_cpu[len + 9] = ALIGN(enc.width, align);
+ if (is_mv_supported == true) {/* disableTwoInstance */
+ if (family_id >= AMDGPU_FAMILY_AI)
+ ib_cpu[len + 11] = 0x01000001;
+ else
+ ib_cpu[len + 11] = 0x01000201;
+ }
len += sizeof(vce_create) / 4;
memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
ib_cpu[len + 2] = enc.fb[0].addr >> 32;
@@ -281,20 +340,24 @@ static void amdgpu_cs_vce_config(void)
memcpy((ib_cpu + len), vce_rdo, sizeof(vce_rdo));
len += sizeof(vce_rdo) / 4;
memcpy((ib_cpu + len), vce_pic_ctrl, sizeof(vce_pic_ctrl));
+ if (is_mv_supported == true)
+ ib_cpu[len + 27] = 0x00000001; /* encSliceMode */
len += sizeof(vce_pic_ctrl) / 4;
r = submit(len, AMDGPU_HW_IP_VCE);
CU_ASSERT_EQUAL(r, 0);
}
-static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc)
+static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc)
{
uint64_t luma_offset, chroma_offset;
- int len = 0, r;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ unsigned luma_size = ALIGN(enc->width, align) * ALIGN(enc->height, 16);
+ int len = 0, i, r;
luma_offset = enc->vbuf.addr;
- chroma_offset = luma_offset + enc->width * enc->height;
+ chroma_offset = luma_offset + luma_size;
memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
len += sizeof(vce_session) / 4;
@@ -309,6 +372,10 @@ static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc)
ib_cpu[len + 3] = enc->cpb.addr;
len += sizeof(vce_context_buffer) / 4;
memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer));
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 2 + i] = luma_size * 1.5 * (i + 2);
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 10 + i] = luma_size * 1.5;
len += sizeof(vce_aux_buffer) / 4;
memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
ib_cpu[len + 2] = enc->fb[0].addr >> 32;
@@ -319,8 +386,10 @@ static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc)
ib_cpu[len + 10] = luma_offset;
ib_cpu[len + 11] = chroma_offset >> 32;
ib_cpu[len + 12] = chroma_offset;
- ib_cpu[len + 73] = 0x7800;
- ib_cpu[len + 74] = 0x7800 + 0x5000;
+ ib_cpu[len + 14] = ALIGN(enc->width, align);
+ ib_cpu[len + 15] = ALIGN(enc->width, align);
+ ib_cpu[len + 73] = luma_size * 1.5;
+ ib_cpu[len + 74] = luma_size * 2.5;
len += sizeof(vce_encode) / 4;
enc->ib_len = len;
if (!enc->two_instance) {
@@ -332,11 +401,13 @@ static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc)
static void amdgpu_cs_vce_encode_p(struct amdgpu_vce_encode *enc)
{
uint64_t luma_offset, chroma_offset;
- int len, r;
+ int len, i, r;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ unsigned luma_size = ALIGN(enc->width, align) * ALIGN(enc->height, 16);
len = (enc->two_instance) ? enc->ib_len : 0;
luma_offset = enc->vbuf.addr;
- chroma_offset = luma_offset + enc->width * enc->height;
+ chroma_offset = luma_offset + luma_size;
if (!enc->two_instance) {
memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
@@ -353,6 +424,10 @@ static void amdgpu_cs_vce_encode_p(struct amdgpu_vce_encode *enc)
ib_cpu[len + 3] = enc->cpb.addr;
len += sizeof(vce_context_buffer) / 4;
memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer));
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 2 + i] = luma_size * 1.5 * (i + 2);
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 10 + i] = luma_size * 1.5;
len += sizeof(vce_aux_buffer) / 4;
memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
ib_cpu[len + 2] = enc->fb[1].addr >> 32;
@@ -364,15 +439,17 @@ static void amdgpu_cs_vce_encode_p(struct amdgpu_vce_encode *enc)
ib_cpu[len + 10] = luma_offset;
ib_cpu[len + 11] = chroma_offset >> 32;
ib_cpu[len + 12] = chroma_offset;
+ ib_cpu[len + 14] = ALIGN(enc->width, align);
+ ib_cpu[len + 15] = ALIGN(enc->width, align);
ib_cpu[len + 18] = 0;
ib_cpu[len + 19] = 0;
ib_cpu[len + 56] = 3;
ib_cpu[len + 57] = 0;
ib_cpu[len + 58] = 0;
- ib_cpu[len + 59] = 0x7800;
- ib_cpu[len + 60] = 0x7800 + 0x5000;
+ ib_cpu[len + 59] = luma_size * 1.5;
+ ib_cpu[len + 60] = luma_size * 2.5;
ib_cpu[len + 73] = 0;
- ib_cpu[len + 74] = 0x5000;
+ ib_cpu[len + 74] = luma_size;
ib_cpu[len + 81] = 1;
ib_cpu[len + 82] = 1;
len += sizeof(vce_encode) / 4;
@@ -408,9 +485,10 @@ static void check_result(struct amdgpu_vce_encode *enc)
static void amdgpu_cs_vce_encode(void)
{
uint32_t vbuf_size, bs_size = 0x154000, cpb_size;
- int r;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ int i, r;
- vbuf_size = enc.width * enc.height * 1.5;
+ vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5;
cpb_size = vbuf_size * 10;
num_resources = 0;
alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
@@ -429,7 +507,17 @@ static void amdgpu_cs_vce_encode(void)
r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr);
CU_ASSERT_EQUAL(r, 0);
- memcpy(enc.vbuf.ptr, frame, sizeof(frame));
+
+ memset(enc.vbuf.ptr, 0, vbuf_size);
+ for (i = 0; i < enc.height; ++i) {
+ memcpy(enc.vbuf.ptr, (frame + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+ for (i = 0; i < enc.height / 2; ++i) {
+ memcpy(enc.vbuf.ptr, ((frame + enc.height * enc.width) + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+
r = amdgpu_bo_cpu_unmap(enc.vbuf.handle);
CU_ASSERT_EQUAL(r, 0);
@@ -474,6 +562,180 @@ static void amdgpu_cs_vce_encode(void)
free_resource(&enc.cpb);
}
+static void amdgpu_cs_vce_mv(struct amdgpu_vce_encode *enc)
+{
+ uint64_t luma_offset, chroma_offset;
+ uint64_t mv_ref_luma_offset;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ unsigned luma_size = ALIGN(enc->width, align) * ALIGN(enc->height, 16);
+ int len = 0, i, r;
+
+ luma_offset = enc->vbuf.addr;
+ chroma_offset = luma_offset + luma_size;
+ mv_ref_luma_offset = enc->mvrefbuf.addr;
+
+ memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
+ len += sizeof(vce_session) / 4;
+ memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
+ len += sizeof(vce_taskinfo) / 4;
+ memcpy((ib_cpu + len), vce_bs_buffer, sizeof(vce_bs_buffer));
+ ib_cpu[len + 2] = enc->bs[0].addr >> 32;
+ ib_cpu[len + 3] = enc->bs[0].addr;
+ len += sizeof(vce_bs_buffer) / 4;
+ memcpy((ib_cpu + len), vce_context_buffer, sizeof(vce_context_buffer));
+ ib_cpu[len + 2] = enc->cpb.addr >> 32;
+ ib_cpu[len + 3] = enc->cpb.addr;
+ len += sizeof(vce_context_buffer) / 4;
+ memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer));
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 2 + i] = luma_size * 1.5 * (i + 2);
+ for (i = 0; i < 8; ++i)
+ ib_cpu[len + 10 + i] = luma_size * 1.5;
+ len += sizeof(vce_aux_buffer) / 4;
+ memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
+ ib_cpu[len + 2] = enc->fb[0].addr >> 32;
+ ib_cpu[len + 3] = enc->fb[0].addr;
+ len += sizeof(vce_feedback) / 4;
+ memcpy((ib_cpu + len), vce_mv_buffer, sizeof(vce_mv_buffer));
+ ib_cpu[len + 2] = mv_ref_luma_offset >> 32;
+ ib_cpu[len + 3] = mv_ref_luma_offset;
+ ib_cpu[len + 4] = ALIGN(enc->width, align);
+ ib_cpu[len + 5] = ALIGN(enc->width, align);
+ ib_cpu[len + 6] = luma_size;
+ ib_cpu[len + 7] = enc->mvb.addr >> 32;
+ ib_cpu[len + 8] = enc->mvb.addr;
+ len += sizeof(vce_mv_buffer) / 4;
+ memcpy((ib_cpu + len), vce_encode, sizeof(vce_encode));
+ ib_cpu[len + 2] = 0;
+ ib_cpu[len + 3] = 0;
+ ib_cpu[len + 4] = 0x154000;
+ ib_cpu[len + 9] = luma_offset >> 32;
+ ib_cpu[len + 10] = luma_offset;
+ ib_cpu[len + 11] = chroma_offset >> 32;
+ ib_cpu[len + 12] = chroma_offset;
+ ib_cpu[len + 13] = ALIGN(enc->height, 16);;
+ ib_cpu[len + 14] = ALIGN(enc->width, align);
+ ib_cpu[len + 15] = ALIGN(enc->width, align);
+ /* encDisableMBOffloading-encDisableTwoPipeMode-encInputPicArrayMode-encInputPicAddrMode */
+ ib_cpu[len + 16] = 0x01010000;
+ ib_cpu[len + 18] = 0; /* encPicType */
+ ib_cpu[len + 19] = 0; /* encIdrFlag */
+ ib_cpu[len + 20] = 0; /* encIdrPicId */
+ ib_cpu[len + 21] = 0; /* encMGSKeyPic */
+ ib_cpu[len + 22] = 0; /* encReferenceFlag */
+ ib_cpu[len + 23] = 0; /* encTemporalLayerIndex */
+ ib_cpu[len + 55] = 0; /* pictureStructure */
+ ib_cpu[len + 56] = 0; /* encPicType -ref[0] */
+ ib_cpu[len + 61] = 0; /* pictureStructure */
+ ib_cpu[len + 62] = 0; /* encPicType -ref[1] */
+ ib_cpu[len + 67] = 0; /* pictureStructure */
+ ib_cpu[len + 68] = 0; /* encPicType -ref1 */
+ ib_cpu[len + 81] = 1; /* frameNumber */
+ ib_cpu[len + 82] = 2; /* pictureOrderCount */
+ ib_cpu[len + 83] = 0xffffffff; /* numIPicRemainInRCGOP */
+ ib_cpu[len + 84] = 0xffffffff; /* numPPicRemainInRCGOP */
+ ib_cpu[len + 85] = 0xffffffff; /* numBPicRemainInRCGOP */
+ ib_cpu[len + 86] = 0xffffffff; /* numIRPicRemainInRCGOP */
+ ib_cpu[len + 87] = 0; /* remainedIntraRefreshPictures */
+ len += sizeof(vce_encode) / 4;
+
+ enc->ib_len = len;
+ r = submit(len, AMDGPU_HW_IP_VCE);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void check_mv_result(struct amdgpu_vce_encode *enc)
+{
+ uint64_t sum;
+ uint32_t s = 140790;
+ uint32_t *ptr, size;
+ int i, j, r;
+
+ r = amdgpu_bo_cpu_map(enc->fb[0].handle, (void **)&enc->fb[0].ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ ptr = (uint32_t *)enc->fb[0].ptr;
+ r = amdgpu_bo_cpu_unmap(enc->fb[0].handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_cpu_map(enc->mvb.handle, (void **)&enc->mvb.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ for (j = 0, sum = 0; j < enc->mvbuf_size; ++j)
+ sum += enc->mvb.ptr[j];
+ CU_ASSERT_EQUAL(sum, s);
+ r = amdgpu_bo_cpu_unmap(enc->mvb.handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_cs_vce_encode_mv(void)
+{
+ uint32_t vbuf_size, bs_size = 0x154000, cpb_size;
+ unsigned align = (family_id >= AMDGPU_FAMILY_AI) ? 256 : 16;
+ int i, r;
+
+ vbuf_size = ALIGN(enc.width, align) * ALIGN(enc.height, 16) * 1.5;
+ enc.mvbuf_size = ALIGN(enc.width, 16) * ALIGN(enc.height, 16) / 8;
+ cpb_size = vbuf_size * 10;
+ num_resources = 0;
+ alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.fb[0].handle;
+ alloc_resource(&enc.bs[0], bs_size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.bs[0].handle;
+ alloc_resource(&enc.mvb, enc.mvbuf_size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = enc.mvb.handle;
+ alloc_resource(&enc.vbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.vbuf.handle;
+ alloc_resource(&enc.mvrefbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.mvrefbuf.handle;
+ alloc_resource(&enc.cpb, cpb_size, AMDGPU_GEM_DOMAIN_VRAM);
+ resources[num_resources++] = enc.cpb.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(enc.vbuf.ptr, 0, vbuf_size);
+ for (i = 0; i < enc.height; ++i) {
+ memcpy(enc.vbuf.ptr, (frame + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+ for (i = 0; i < enc.height / 2; ++i) {
+ memcpy(enc.vbuf.ptr, ((frame + enc.height * enc.width) + i * enc.width), enc.width);
+ enc.vbuf.ptr += ALIGN(enc.width, align);
+ }
+
+ r = amdgpu_bo_cpu_unmap(enc.vbuf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_cpu_map(enc.mvrefbuf.handle, (void **)&enc.mvrefbuf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(enc.mvrefbuf.ptr, 0, vbuf_size);
+ for (i = 0; i < enc.height; ++i) {
+ memcpy(enc.mvrefbuf.ptr, (frame + (enc.height - i -1) * enc.width), enc.width);
+ enc.mvrefbuf.ptr += ALIGN(enc.width, align);
+ }
+ for (i = 0; i < enc.height / 2; ++i) {
+ memcpy(enc.mvrefbuf.ptr,
+ ((frame + enc.height * enc.width) + (enc.height / 2 - i -1) * enc.width), enc.width);
+ enc.mvrefbuf.ptr += ALIGN(enc.width, align);
+ }
+
+ r = amdgpu_bo_cpu_unmap(enc.mvrefbuf.handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ amdgpu_cs_vce_config();
+
+ vce_taskinfo[3] = 3;
+ amdgpu_cs_vce_mv(&enc);
+ check_mv_result(&enc);
+
+ free_resource(&enc.fb[0]);
+ free_resource(&enc.bs[0]);
+ free_resource(&enc.vbuf);
+ free_resource(&enc.cpb);
+ free_resource(&enc.mvrefbuf);
+ free_resource(&enc.mvb);
+}
+
static void amdgpu_cs_vce_destroy(void)
{
int len, r;
diff --git a/tests/amdgpu/vcn_tests.c b/tests/amdgpu/vcn_tests.c
new file mode 100644
index 00000000..859ec496
--- /dev/null
+++ b/tests/amdgpu/vcn_tests.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2017 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 <stdio.h>
+#include <inttypes.h>
+
+#include "CUnit/Basic.h"
+
+#include "util_math.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include "decode_messages.h"
+
+#define IB_SIZE 4096
+#define MAX_RESOURCES 16
+
+struct amdgpu_vcn_bo {
+ amdgpu_bo_handle handle;
+ amdgpu_va_handle va_handle;
+ uint64_t addr;
+ uint64_t size;
+ uint8_t *ptr;
+};
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+static uint32_t family_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 amdgpu_bo_handle resources[MAX_RESOURCES];
+static unsigned num_resources;
+
+static void amdgpu_cs_vcn_dec_create(void);
+static void amdgpu_cs_vcn_dec_decode(void);
+static void amdgpu_cs_vcn_dec_destroy(void);
+
+static void amdgpu_cs_vcn_enc_create(void);
+static void amdgpu_cs_vcn_enc_encode(void);
+static void amdgpu_cs_vcn_enc_destroy(void);
+
+CU_TestInfo vcn_tests[] = {
+
+ { "VCN DEC create", amdgpu_cs_vcn_dec_create },
+ { "VCN DEC decode", amdgpu_cs_vcn_dec_decode },
+ { "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 destroy", amdgpu_cs_vcn_enc_destroy },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_vcn_tests_enable(void)
+{
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ family_id = device_handle->info.family_id;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+
+ if (family_id < AMDGPU_FAMILY_RV) {
+ printf("\n\nThe ASIC NOT support VCN, suite disabled\n");
+ return CU_FALSE;
+ }
+
+ return CU_TRUE;
+}
+
+int suite_vcn_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ family_id = device_handle->info.family_id;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ if (r)
+ return CUE_SINIT_FAILED;
+
+ r = amdgpu_bo_alloc_and_map(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;
+
+ return CUE_SUCCESS;
+}
+
+int suite_vcn_tests_clean(void)
+{
+ int r;
+
+ 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(device_handle);
+ if (r)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+static int submit(unsigned ndw, unsigned ip)
+{
+ 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;
+ int r;
+
+ ib_info.ib_mc_address = ib_mc_address;
+ ib_info.size = ndw;
+
+ ibs_request.ip_type = ip;
+
+ r = amdgpu_bo_list_create(device_handle, num_resources, resources,
+ NULL, &ibs_request.resources);
+ if (r)
+ return r;
+
+ 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 = ip;
+ 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 alloc_resource(struct amdgpu_vcn_bo *vcn_bo,
+ unsigned size, unsigned domain)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle va_handle;
+ uint64_t va = 0;
+ int r;
+
+ req.alloc_size = ALIGN(size, 4096);
+ req.preferred_heap = domain;
+ r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_va_range_alloc(device_handle,
+ amdgpu_gpu_va_range_general,
+ req.alloc_size, 1, 0, &va,
+ &va_handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ vcn_bo->addr = va;
+ vcn_bo->handle = buf_handle;
+ vcn_bo->size = req.alloc_size;
+ vcn_bo->va_handle = va_handle;
+ r = amdgpu_bo_cpu_map(vcn_bo->handle, (void **)&vcn_bo->ptr);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vcn_bo->ptr, 0, size);
+ r = amdgpu_bo_cpu_unmap(vcn_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void free_resource(struct amdgpu_vcn_bo *vcn_bo)
+{
+ int r;
+
+ r = amdgpu_bo_va_op(vcn_bo->handle, 0, vcn_bo->size,
+ vcn_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_va_range_free(vcn_bo->va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_free(vcn_bo->handle);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(vcn_bo, 0, sizeof(*vcn_bo));
+}
+
+static void vcn_dec_cmd(uint64_t addr, unsigned cmd, int *idx)
+{
+ ib_cpu[(*idx)++] = 0x81C4;
+ ib_cpu[(*idx)++] = addr;
+ ib_cpu[(*idx)++] = 0x81C5;
+ ib_cpu[(*idx)++] = addr >> 32;
+ ib_cpu[(*idx)++] = 0x81C3;
+ ib_cpu[(*idx)++] = cmd << 1;
+}
+
+static void amdgpu_cs_vcn_dec_create(void)
+{
+ struct amdgpu_vcn_bo msg_buf;
+ int len, r;
+
+ num_resources = 0;
+ alloc_resource(&msg_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = msg_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(msg_buf.ptr, 0, 4096);
+ memcpy(msg_buf.ptr, vcn_dec_create_msg, sizeof(vcn_dec_create_msg));
+
+ len = 0;
+ ib_cpu[len++] = 0x81C4;
+ ib_cpu[len++] = msg_buf.addr;
+ ib_cpu[len++] = 0x81C5;
+ ib_cpu[len++] = msg_buf.addr >> 32;
+ ib_cpu[len++] = 0x81C3;
+ ib_cpu[len++] = 0;
+ for (; len % 16; ) {
+ ib_cpu[len++] = 0x81ff;
+ ib_cpu[len++] = 0;
+ }
+
+ r = submit(len, AMDGPU_HW_IP_VCN_DEC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&msg_buf);
+}
+
+static void amdgpu_cs_vcn_dec_decode(void)
+{
+ const unsigned dpb_size = 15923584, dt_size = 737280;
+ 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;
+ uint8_t *dec;
+
+ size = 4*1024; /* msg */
+ size += 4*1024; /* fb */
+ size += 4096; /*it_scaling_table*/
+ size += ALIGN(sizeof(uvd_bitstream), 4*1024);
+ size += ALIGN(dpb_size, 4*1024);
+ size += ALIGN(dt_size, 4*1024);
+
+ num_resources = 0;
+ alloc_resource(&dec_buf, size, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = dec_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(dec_buf.handle, (void **)&dec_buf.ptr);
+ dec = dec_buf.ptr;
+
+ CU_ASSERT_EQUAL(r, 0);
+ memset(dec_buf.ptr, 0, size);
+ memcpy(dec_buf.ptr, vcn_dec_decode_msg, sizeof(vcn_dec_decode_msg));
+ memcpy(dec_buf.ptr + sizeof(vcn_dec_decode_msg),
+ avc_decode_msg, sizeof(avc_decode_msg));
+
+ dec += 4*1024;
+ dec += 4*1024;
+ memcpy(dec, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
+
+ dec += 4*1024;
+ memcpy(dec, uvd_bitstream, sizeof(uvd_bitstream));
+
+ dec += ALIGN(sizeof(uvd_bitstream), 4*1024);
+
+ dec += ALIGN(dpb_size, 4*1024);
+
+ msg_addr = dec_buf.addr;
+ fb_addr = msg_addr + 4*1024;
+ it_addr = fb_addr + 4*1024;
+ bs_addr = it_addr + 4*1024;
+ dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
+ ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
+ dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
+
+ len = 0;
+ vcn_dec_cmd(msg_addr, 0x0, &len);
+ vcn_dec_cmd(dpb_addr, 0x1, &len);
+ vcn_dec_cmd(dt_addr, 0x2, &len);
+ vcn_dec_cmd(fb_addr, 0x3, &len);
+ vcn_dec_cmd(bs_addr, 0x100, &len);
+ vcn_dec_cmd(it_addr, 0x204, &len);
+ vcn_dec_cmd(ctx_addr, 0x206, &len);
+
+ ib_cpu[len++] = 0x81C6;
+ ib_cpu[len++] = 0x1;
+ for (; len % 16; ) {
+ ib_cpu[len++] = 0x81ff;
+ ib_cpu[len++] = 0;
+ }
+
+ r = submit(len, AMDGPU_HW_IP_VCN_DEC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (i = 0, sum = 0; i < dt_size; ++i)
+ sum += dec[i];
+
+ CU_ASSERT_EQUAL(sum, SUM_DECODE);
+
+ free_resource(&dec_buf);
+}
+
+static void amdgpu_cs_vcn_dec_destroy(void)
+{
+ struct amdgpu_vcn_bo msg_buf;
+ int len, r;
+
+ num_resources = 0;
+ alloc_resource(&msg_buf, 1024, AMDGPU_GEM_DOMAIN_GTT);
+ resources[num_resources++] = msg_buf.handle;
+ resources[num_resources++] = ib_handle;
+
+ r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(msg_buf.ptr, 0, 1024);
+ memcpy(msg_buf.ptr, vcn_dec_destroy_msg, sizeof(vcn_dec_destroy_msg));
+
+ len = 0;
+ ib_cpu[len++] = 0x81C4;
+ ib_cpu[len++] = msg_buf.addr;
+ ib_cpu[len++] = 0x81C5;
+ ib_cpu[len++] = msg_buf.addr >> 32;
+ ib_cpu[len++] = 0x81C3;
+ ib_cpu[len++] = 0;
+ for (; len % 16; ) {
+ ib_cpu[len++] = 0x81ff;
+ ib_cpu[len++] = 0;
+ }
+
+ r = submit(len, AMDGPU_HW_IP_VCN_DEC);
+ CU_ASSERT_EQUAL(r, 0);
+
+ free_resource(&msg_buf);
+}
+
+static void amdgpu_cs_vcn_enc_create(void)
+{
+ /* TODO */
+}
+
+static void amdgpu_cs_vcn_enc_encode(void)
+{
+ /* TODO */
+}
+
+static void amdgpu_cs_vcn_enc_destroy(void)
+{
+ /* TODO */
+}
diff --git a/tests/amdgpu/vm_tests.c b/tests/amdgpu/vm_tests.c
new file mode 100644
index 00000000..69bc4683
--- /dev/null
+++ b/tests/amdgpu/vm_tests.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2017 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 "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static void amdgpu_vmid_reserve_test(void);
+static void amdgpu_vm_unaligned_map(void);
+static void amdgpu_vm_mapping_test(void);
+
+CU_BOOL suite_vm_tests_enable(void)
+{
+ CU_BOOL enable = CU_TRUE;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ if (device_handle->info.family_id == AMDGPU_FAMILY_SI) {
+ printf("\n\nCurrently hangs the CP on this ASIC, VM suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ return enable;
+}
+
+int suite_vm_tests_init(void)
+{
+ int r;
+
+ r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+
+ if (r) {
+ if ((r == -EACCES) && (errno == EACCES))
+ printf("\n\nError:%s. "
+ "Hint:Try to run this test program as root.",
+ strerror(errno));
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_vm_tests_clean(void)
+{
+ int r = amdgpu_device_deinitialize(device_handle);
+
+ if (r == 0)
+ return CUE_SUCCESS;
+ else
+ return CUE_SCLEAN_FAILED;
+}
+
+
+CU_TestInfo vm_tests[] = {
+ { "resere vmid test", amdgpu_vmid_reserve_test },
+ { "unaligned map", amdgpu_vm_unaligned_map },
+ { "vm mapping test", amdgpu_vm_mapping_test },
+ CU_TEST_INFO_NULL,
+};
+
+static void amdgpu_vmid_reserve_test(void)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle ib_result_handle;
+ void *ib_result_cpu;
+ uint64_t ib_result_mc_address;
+ struct amdgpu_cs_request ibs_request;
+ struct amdgpu_cs_ib_info ib_info;
+ struct amdgpu_cs_fence fence_status;
+ uint32_t expired, flags;
+ int i, r;
+ amdgpu_bo_list_handle bo_list;
+ amdgpu_va_handle va_handle;
+ static uint32_t *ptr;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ flags = 0;
+ r = amdgpu_vm_reserve_vmid(device_handle, flags);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &ib_result_handle, &ib_result_cpu,
+ &ib_result_mc_address, &va_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
+ &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ptr = ib_result_cpu;
+
+ for (i = 0; i < 16; ++i)
+ ptr[i] = 0xffff1000;
+
+ memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
+ ib_info.ib_mc_address = ib_result_mc_address;
+ ib_info.size = 16;
+
+ memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ 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_GFX;
+ 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 = 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);
+
+ flags = 0;
+ r = amdgpu_vm_unreserve_vmid(device_handle, flags);
+ CU_ASSERT_EQUAL(r, 0);
+
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_vm_unaligned_map(void)
+{
+ const uint64_t map_size = (4ULL << 30) - (2 << 12);
+ struct amdgpu_bo_alloc_request request = {};
+ amdgpu_bo_handle buf_handle;
+ amdgpu_va_handle handle;
+ uint64_t vmc_addr;
+ int r;
+
+ request.alloc_size = 4ULL << 30;
+ request.phys_alignment = 4096;
+ request.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;
+ request.flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+
+ r = amdgpu_bo_alloc(device_handle, &request, &buf_handle);
+ /* Don't let the test fail if the device doesn't have enough VRAM */
+ if (r)
+ return;
+
+ r = amdgpu_va_range_alloc(device_handle, amdgpu_gpu_va_range_general,
+ 4ULL << 30, 1ULL << 30, 0, &vmc_addr,
+ &handle, 0);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ goto error_va_alloc;
+
+ vmc_addr += 1 << 12;
+
+ r = amdgpu_bo_va_op(buf_handle, 0, map_size, vmc_addr, 0,
+ AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ if (r)
+ goto error_va_alloc;
+
+ amdgpu_bo_va_op(buf_handle, 0, map_size, vmc_addr, 0,
+ AMDGPU_VA_OP_UNMAP);
+
+error_va_alloc:
+ amdgpu_bo_free(buf_handle);
+}
+
+static void amdgpu_vm_mapping_test(void)
+{
+ struct amdgpu_bo_alloc_request req = {0};
+ struct drm_amdgpu_info_device dev_info;
+ const uint64_t size = 4096;
+ amdgpu_bo_handle buf;
+ uint64_t addr;
+ int r;
+
+ req.alloc_size = size;
+ req.phys_alignment = 0;
+ req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
+ req.flags = 0;
+
+ r = amdgpu_bo_alloc(device_handle, &req, &buf);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_query_info(device_handle, AMDGPU_INFO_DEV_INFO,
+ sizeof(dev_info), &dev_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ addr = dev_info.virtual_address_offset;
+ r = amdgpu_bo_va_op(buf, 0, size, addr, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ addr = dev_info.virtual_address_max - size;
+ r = amdgpu_bo_va_op(buf, 0, size, addr, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ if (dev_info.high_va_offset) {
+ addr = dev_info.high_va_offset;
+ r = amdgpu_bo_va_op(buf, 0, size, addr, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+
+ addr = dev_info.high_va_max - size;
+ r = amdgpu_bo_va_op(buf, 0, size, addr, 0, AMDGPU_VA_OP_MAP);
+ CU_ASSERT_EQUAL(r, 0);
+ }
+
+ amdgpu_bo_free(buf);
+}
diff --git a/tests/drmdevice.c b/tests/drmdevice.c
index 9dd5098a..f1c1cd3a 100644
--- a/tests/drmdevice.c
+++ b/tests/drmdevice.c
@@ -36,67 +36,66 @@ static void
print_device_info(drmDevicePtr device, int i, bool print_revision)
{
printf("device[%i]\n", i);
- printf("\tavailable_nodes %04x\n", device->available_nodes);
- printf("\tnodes\n");
+ printf("+-> available_nodes %#04x\n", device->available_nodes);
+ printf("+-> nodes\n");
for (int j = 0; j < DRM_NODE_MAX; j++)
if (device->available_nodes & 1 << j)
- printf("\t\tnodes[%d] %s\n", j, device->nodes[j]);
+ printf("| +-> nodes[%d] %s\n", j, device->nodes[j]);
- printf("\tbustype %04x\n", device->bustype);
- printf("\tbusinfo\n");
+ printf("+-> bustype %04x\n", device->bustype);
if (device->bustype == DRM_BUS_PCI) {
- printf("\t\tpci\n");
- printf("\t\t\tdomain\t%04x\n",device->businfo.pci->domain);
- printf("\t\t\tbus\t%02x\n", device->businfo.pci->bus);
- printf("\t\t\tdev\t%02x\n", device->businfo.pci->dev);
- printf("\t\t\tfunc\t%1u\n", device->businfo.pci->func);
-
- printf("\tdeviceinfo\n");
- printf("\t\tpci\n");
- printf("\t\t\tvendor_id\t%04x\n", device->deviceinfo.pci->vendor_id);
- printf("\t\t\tdevice_id\t%04x\n", device->deviceinfo.pci->device_id);
- printf("\t\t\tsubvendor_id\t%04x\n", device->deviceinfo.pci->subvendor_id);
- printf("\t\t\tsubdevice_id\t%04x\n", device->deviceinfo.pci->subdevice_id);
+ printf("| +-> pci\n");
+ printf("| +-> domain %04x\n",device->businfo.pci->domain);
+ printf("| +-> bus %02x\n", device->businfo.pci->bus);
+ printf("| +-> dev %02x\n", device->businfo.pci->dev);
+ printf("| +-> func %1u\n", device->businfo.pci->func);
+
+ printf("+-> deviceinfo\n");
+ printf(" +-> pci\n");
+ printf(" +-> vendor_id %04x\n", device->deviceinfo.pci->vendor_id);
+ printf(" +-> device_id %04x\n", device->deviceinfo.pci->device_id);
+ printf(" +-> subvendor_id %04x\n", device->deviceinfo.pci->subvendor_id);
+ printf(" +-> subdevice_id %04x\n", device->deviceinfo.pci->subdevice_id);
if (print_revision)
- printf("\t\t\trevision_id\t%02x\n", device->deviceinfo.pci->revision_id);
+ printf(" +-> revision_id %02x\n", device->deviceinfo.pci->revision_id);
else
- printf("\t\t\trevision_id\tIGNORED\n");
+ printf(" +-> revision_id IGNORED\n");
} else if (device->bustype == DRM_BUS_USB) {
- printf("\t\tusb\n");
- printf("\t\t\tbus\t%03u\n", device->businfo.usb->bus);
- printf("\t\t\tdev\t%03u\n", device->businfo.usb->dev);
-
- printf("\tdeviceinfo\n");
- printf("\t\tusb\n");
- printf("\t\t\tvendor\t%04x\n", device->deviceinfo.usb->vendor);
- printf("\t\t\tproduct\t%04x\n", device->deviceinfo.usb->product);
+ printf("| +-> usb\n");
+ printf("| +-> bus %03u\n", device->businfo.usb->bus);
+ printf("| +-> dev %03u\n", device->businfo.usb->dev);
+
+ printf("+-> deviceinfo\n");
+ printf(" +-> usb\n");
+ printf(" +-> vendor %04x\n", device->deviceinfo.usb->vendor);
+ printf(" +-> product %04x\n", device->deviceinfo.usb->product);
} else if (device->bustype == DRM_BUS_PLATFORM) {
char **compatible = device->deviceinfo.platform->compatible;
- printf("\t\tplatform\n");
- printf("\t\t\tfullname\t%s\n", device->businfo.platform->fullname);
+ printf("| +-> platform\n");
+ printf("| +-> fullname\t%s\n", device->businfo.platform->fullname);
- printf("\tdeviceinfo\n");
- printf("\t\tplatform\n");
- printf("\t\t\tcompatible\n");
+ printf("+-> deviceinfo\n");
+ printf(" +-> platform\n");
+ printf(" +-> compatible\n");
while (*compatible) {
- printf("\t\t\t\t%s\n", *compatible);
+ printf(" %s\n", *compatible);
compatible++;
}
} else if (device->bustype == DRM_BUS_HOST1X) {
- char **compatible = device->deviceinfo.platform->compatible;
+ char **compatible = device->deviceinfo.host1x->compatible;
- printf("\t\thost1x\n");
- printf("\t\t\tfullname\t%s\n", device->businfo.host1x->fullname);
+ printf("| +-> host1x\n");
+ printf("| +-> fullname\t%s\n", device->businfo.host1x->fullname);
- printf("\tdeviceinfo\n");
- printf("\t\tplatform\n");
- printf("\t\t\tcompatible\n");
+ printf("+-> deviceinfo\n");
+ printf(" +-> host1x\n");
+ printf(" +-> compatible\n");
while (*compatible) {
- printf("\t\t\t\t%s\n", *compatible);
+ printf(" %s\n", *compatible);
compatible++;
}
} else {
@@ -112,12 +111,16 @@ main(void)
drmDevicePtr device;
int fd, ret, max_devices;
+ printf("--- Checking the number of DRM device available ---\n");
max_devices = drmGetDevices2(0, NULL, 0);
if (max_devices <= 0) {
- printf("drmGetDevices2() has returned %d\n", max_devices);
- return -1;
+ printf("drmGetDevices2() has not found any devices (errno=%d)\n",
+ -max_devices);
+ return 77;
}
+ printf("--- Devices reported %d ---\n", max_devices);
+
devices = calloc(max_devices, sizeof(drmDevicePtr));
if (devices == NULL) {
@@ -125,6 +128,7 @@ main(void)
return -1;
}
+ printf("--- Retrieving devices information (PCI device revision is ignored) ---\n");
ret = drmGetDevices2(0, devices, max_devices);
if (ret < 0) {
printf("drmGetDevices2() returned an error %d\n", ret);
@@ -137,13 +141,14 @@ main(void)
for (int j = 0; j < DRM_NODE_MAX; j++) {
if (devices[i]->available_nodes & 1 << j) {
- printf("Opening device %d node %s\n", i, devices[i]->nodes[j]);
+ printf("--- Opening device node %s ---\n", devices[i]->nodes[j]);
fd = open(devices[i]->nodes[j], O_RDONLY | O_CLOEXEC, 0);
if (fd < 0) {
printf("Failed - %s (%d)\n", strerror(errno), errno);
continue;
}
+ printf("--- Retrieving device info, for node %s ---\n", devices[i]->nodes[j]);
if (drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, &device) == 0) {
print_device_info(device, i, true);
drmFreeDevice(&device);
diff --git a/tests/drmsl.c b/tests/drmsl.c
index d0ac0efa..d1b59a86 100644
--- a/tests/drmsl.c
+++ b/tests/drmsl.c
@@ -106,7 +106,9 @@ static double do_time(int size, int iter)
return usec;
}
-static void print_neighbors(void *list, unsigned long key)
+static void print_neighbors(void *list, unsigned long key,
+ unsigned long expected_prev,
+ unsigned long expected_next)
{
unsigned long prev_key = 0;
unsigned long next_key = 0;
@@ -119,6 +121,16 @@ static void print_neighbors(void *list, unsigned long key)
&next_key, &next_value);
printf("Neighbors of %5lu: %d %5lu %5lu\n",
key, retval, prev_key, next_key);
+ if (prev_key != expected_prev) {
+ fprintf(stderr, "Unexpected neighbor: %5lu. Expected: %5lu\n",
+ prev_key, expected_prev);
+ exit(1);
+ }
+ if (next_key != expected_next) {
+ fprintf(stderr, "Unexpected neighbor: %5lu. Expected: %5lu\n",
+ next_key, expected_next);
+ exit(1);
+ }
}
int main(void)
@@ -138,13 +150,13 @@ int main(void)
print(list);
printf("\n==============================\n\n");
- print_neighbors(list, 0);
- print_neighbors(list, 50);
- print_neighbors(list, 51);
- print_neighbors(list, 123);
- print_neighbors(list, 200);
- print_neighbors(list, 213);
- print_neighbors(list, 256);
+ print_neighbors(list, 0, 0, 50);
+ print_neighbors(list, 50, 0, 50);
+ print_neighbors(list, 51, 50, 123);
+ print_neighbors(list, 123, 50, 123);
+ print_neighbors(list, 200, 123, 213);
+ print_neighbors(list, 213, 123, 213);
+ print_neighbors(list, 256, 213, 256);
printf("\n==============================\n\n");
drmSLDelete(list, 50);
diff --git a/tests/drmstat.c b/tests/drmstat.c
deleted file mode 100644
index 023aa069..00000000
--- a/tests/drmstat.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* drmstat.c -- DRM device status and testing program
- * Created: Tue Jan 5 08:19:24 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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
- * PRECISION INSIGHT 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.
- *
- * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <getopt.h>
-#include <strings.h>
-#include <errno.h>
-#include <signal.h>
-#include <fcntl.h>
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
-#include "xf86drm.h"
-
-int sigio_fd;
-
-static double usec(struct timeval *end, struct timeval *start)
-{
- double e = end->tv_sec * 1000000 + end->tv_usec;
- double s = start->tv_sec * 1000000 + start->tv_usec;
-
- return e - s;
-}
-
-static void getversion(int fd)
-{
- drmVersionPtr version;
-
- version = drmGetVersion(fd);
- if (version) {
- printf( "Name: %s\n", version->name ? version->name : "?" );
- printf( " Version: %d.%d.%d\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel );
- printf( " Date: %s\n", version->date ? version->date : "?" );
- printf( " Desc: %s\n", version->desc ? version->desc : "?" );
- drmFreeVersion(version);
- } else {
- printf( "No driver available\n" );
- }
-}
-
-static void process_sigio(char *device)
-{
- int fd;
-
- if ((fd = open(device, 0)) < 0) {
- drmError(-errno, __func__);
- exit(1);
- }
-
- sigio_fd = fd;
- for (;;) sleep(60);
-}
-
-int main(int argc, char **argv)
-{
- int c;
- int r = 0;
- int fd = -1;
- drm_handle_t handle;
- void *address;
- char *pt;
- unsigned long count;
- unsigned long offset;
- unsigned long size;
- drm_context_t context;
- int loops;
- char buf[1024];
- int i;
- drmBufInfoPtr info;
- drmBufMapPtr bufs;
- drmLockPtr lock;
- int secs;
-
- while ((c = getopt(argc, argv,
- "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF)
- switch (c) {
- case 'F':
- count = strtoul(optarg, NULL, 0);
- if (!fork()) {
- dup(fd);
- sleep(count);
- }
- close(fd);
- break;
- case 'v': getversion(fd); break;
- case 'X':
- if ((r = drmCreateContext(fd, &context))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf( "Got %d\n", context);
- break;
- case 'S':
- process_sigio(optarg);
- break;
- case 'C':
- if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) {
- drmError(r, argv[0]);
- return 1;
- }
- break;
- case 'c':
- if ((r = drmSetBusid(fd,optarg))) {
- drmError(r, argv[0]);
- return 1;
- }
- break;
- case 'o':
- if ((fd = drmOpen(optarg, NULL)) < 0) {
- drmError(fd, argv[0]);
- return 1;
- }
- break;
- case 'O':
- if ((fd = drmOpen(NULL, optarg)) < 0) {
- drmError(fd, argv[0]);
- return 1;
- }
- break;
- case 'B': /* Test buffer allocation */
- count = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, &pt, 0);
- secs = strtoul(pt+1, NULL, 0);
- {
- drmDMAReq dma;
- int *indices, *sizes;
-
- indices = alloca(sizeof(*indices) * count);
- sizes = alloca(sizeof(*sizes) * count);
- dma.context = context;
- dma.send_count = 0;
- dma.request_count = count;
- dma.request_size = size;
- dma.request_list = indices;
- dma.request_sizes = sizes;
- dma.flags = DRM_DMA_WAIT;
- if ((r = drmDMA(fd, &dma))) {
- drmError(r, argv[0]);
- return 1;
- }
- for (i = 0; i < dma.granted_count; i++) {
- printf("%5d: index = %d, size = %d\n",
- i, dma.request_list[i], dma.request_sizes[i]);
- }
- sleep(secs);
- drmFreeBufs(fd, dma.granted_count, indices);
- }
- break;
- case 'b':
- count = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) {
- drmError(r, argv[0]);
- return 1;
- }
- if (!(info = drmGetBufInfo(fd))) {
- drmError(0, argv[0]);
- return 1;
- }
- for (i = 0; i < info->count; i++) {
- printf("%5d buffers of size %6d (low = %d, high = %d)\n",
- info->list[i].count,
- info->list[i].size,
- info->list[i].low_mark,
- info->list[i].high_mark);
- }
- if ((r = drmMarkBufs(fd, 0.50, 0.80))) {
- drmError(r, argv[0]);
- return 1;
- }
- if (!(info = drmGetBufInfo(fd))) {
- drmError(0, argv[0]);
- return 1;
- }
- for (i = 0; i < info->count; i++) {
- printf("%5d buffers of size %6d (low = %d, high = %d)\n",
- info->list[i].count,
- info->list[i].size,
- info->list[i].low_mark,
- info->list[i].high_mark);
- }
- printf("===== /proc/dri/0/mem =====\n");
- sprintf(buf, "cat /proc/dri/0/mem");
- system(buf);
-#if 1
- if (!(bufs = drmMapBufs(fd))) {
- drmError(0, argv[0]);
- return 1;
- }
- printf("===============================\n");
- printf( "%d bufs\n", bufs->count);
- for (i = 0; i < bufs->count; i++) {
- printf( " %4d: %8d bytes at %p\n",
- i,
- bufs->list[i].total,
- bufs->list[i].address);
- }
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
-#endif
- break;
- case 'f':
- offset = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- handle = 0;
- if ((r = drmAddMap(fd, offset, size,
- DRM_FRAME_BUFFER, 0, &handle))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%08lx:0x%04lx added\n", offset, size);
- printf("===== /proc/dri/0/mem =====\n");
- sprintf(buf, "cat /proc/dri/0/mem");
- system(buf);
- break;
- case 'r':
- case 'R':
- offset = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- handle = 0;
- if ((r = drmAddMap(fd, offset, size,
- DRM_REGISTERS,
- c == 'R' ? DRM_READ_ONLY : 0,
- &handle))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%08lx:0x%04lx added\n", offset, size);
- printf("===== /proc/dri/0/mem =====\n");
- sprintf(buf, "cat /proc/dri/0/mem");
- system(buf);
- break;
- case 's':
- size = strtoul(optarg, &pt, 0);
- handle = 0;
- if ((r = drmAddMap(fd, 0, size,
- DRM_SHM, DRM_CONTAINS_LOCK,
- &handle))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%04lx byte shm added at 0x%08lx\n", size, handle);
- sprintf(buf, "cat /proc/dri/0/vm");
- system(buf);
- break;
- case 'P':
- offset = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- address = NULL;
- if ((r = drmMap(fd, offset, size, &address))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
- offset, size, address, getpid());
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
- mprotect((void *)offset, size, PROT_READ);
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
- break;
- case 'w':
- case 'W':
- offset = strtoul(optarg, &pt, 0);
- size = strtoul(pt+1, NULL, 0);
- address = NULL;
- if ((r = drmMap(fd, offset, size, &address))) {
- drmError(r, argv[0]);
- return 1;
- }
- printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
- offset, size, address, getpid());
- printf("===== /proc/%d/maps =====\n", getpid());
- sprintf(buf, "cat /proc/%d/maps", getpid());
- system(buf);
- printf("===== /proc/dri/0/mem =====\n");
- sprintf(buf, "cat /proc/dri/0/mem");
- system(buf);
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
- printf("===== READING =====\n");
- for (i = 0; i < 0x10; i++)
- printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
- printf("\n");
- if (c == 'w') {
- printf("===== WRITING =====\n");
- for (i = 0; i < size; i+=2) {
- ((char *)address)[i] = i & 0xff;
- ((char *)address)[i+1] = i & 0xff;
- }
- }
- printf("===== READING =====\n");
- for (i = 0; i < 0x10; i++)
- printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
- printf("\n");
- printf("===== /proc/dri/0/vma =====\n");
- sprintf(buf, "cat /proc/dri/0/vma");
- system(buf);
- break;
- case 'L':
- context = strtoul(optarg, &pt, 0);
- offset = strtoul(pt+1, &pt, 0);
- size = strtoul(pt+1, &pt, 0);
- loops = strtoul(pt+1, NULL, 0);
- address = NULL;
- if ((r = drmMap(fd, offset, size, &address))) {
- drmError(r, argv[0]);
- return 1;
- }
- lock = address;
-#if 1
- {
- int counter = 0;
- struct timeval loop_start, loop_end;
- struct timeval lock_start, lock_end;
- double wt;
-#define HISTOSIZE 9
- int histo[HISTOSIZE];
- int output = 0;
- int fast = 0;
-
- if (loops < 0) {
- loops = -loops;
- ++output;
- }
-
- for (i = 0; i < HISTOSIZE; i++) histo[i] = 0;
-
- gettimeofday(&loop_start, NULL);
- for (i = 0; i < loops; i++) {
- gettimeofday(&lock_start, NULL);
- DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast);
- gettimeofday(&lock_end, NULL);
- DRM_UNLOCK(fd,lock,context);
- ++counter;
- wt = usec(&lock_end, &lock_start);
- if (wt <= 2.5) ++histo[8];
- if (wt < 5.0) ++histo[0];
- else if (wt < 50.0) ++histo[1];
- else if (wt < 500.0) ++histo[2];
- else if (wt < 5000.0) ++histo[3];
- else if (wt < 50000.0) ++histo[4];
- else if (wt < 500000.0) ++histo[5];
- else if (wt < 5000000.0) ++histo[6];
- else ++histo[7];
- if (output) printf( "%.2f uSec, %d fast\n", wt, fast);
- }
- gettimeofday(&loop_end, NULL);
- printf( "Average wait time = %.2f usec, %d fast\n",
- usec(&loop_end, &loop_start) / counter, fast);
- printf( "%9d <= 2.5 uS\n", histo[8]);
- printf( "%9d < 5 uS\n", histo[0]);
- printf( "%9d < 50 uS\n", histo[1]);
- printf( "%9d < 500 uS\n", histo[2]);
- printf( "%9d < 5000 uS\n", histo[3]);
- printf( "%9d < 50000 uS\n", histo[4]);
- printf( "%9d < 500000 uS\n", histo[5]);
- printf( "%9d < 5000000 uS\n", histo[6]);
- printf( "%9d >= 5000000 uS\n", histo[7]);
- }
-#else
- printf( "before lock: 0x%08x\n", lock->lock);
- printf( "lock: 0x%08x\n", lock->lock);
- sleep(5);
- printf( "unlock: 0x%08x\n", lock->lock);
-#endif
- break;
- default:
- fprintf( stderr, "Usage: drmstat [options]\n" );
- return 1;
- }
-
- return r;
-}
-
-int xf86ConfigDRI[10];
diff --git a/tests/etnaviv/Makefile.am b/tests/etnaviv/Makefile.am
index 06318643..3e0c6120 100644
--- a/tests/etnaviv/Makefile.am
+++ b/tests/etnaviv/Makefile.am
@@ -1,4 +1,5 @@
AM_CFLAGS = \
+ -fvisibility=hidden \
-I $(top_srcdir)/include/drm \
-I $(top_srcdir)/etnaviv \
-I $(top_srcdir)
@@ -28,6 +29,7 @@ etnaviv_2d_test_SOURCES = \
write_bmp.h
etnaviv_cmd_stream_test_LDADD = \
+ $(top_builddir)/libdrm.la \
$(top_builddir)/etnaviv/libdrm_etnaviv.la
etnaviv_cmd_stream_test_SOURCES = \
diff --git a/tests/etnaviv/etnaviv_2d_test.c b/tests/etnaviv/etnaviv_2d_test.c
index 10751c73..8dd77b66 100644
--- a/tests/etnaviv/etnaviv_2d_test.c
+++ b/tests/etnaviv/etnaviv_2d_test.c
@@ -24,10 +24,6 @@
* Christian Gmeiner <christian.gmeiner@gmail.com>
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
diff --git a/tests/etnaviv/etnaviv_bo_cache_test.c b/tests/etnaviv/etnaviv_bo_cache_test.c
index fb01f8d3..7fb06293 100644
--- a/tests/etnaviv/etnaviv_bo_cache_test.c
+++ b/tests/etnaviv/etnaviv_bo_cache_test.c
@@ -24,10 +24,6 @@
* Christian Gmeiner <christian.gmeiner@gmail.com>
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
#undef NDEBUG
#include <assert.h>
diff --git a/tests/etnaviv/meson.build b/tests/etnaviv/meson.build
new file mode 100644
index 00000000..8b4a3cfb
--- /dev/null
+++ b/tests/etnaviv/meson.build
@@ -0,0 +1,45 @@
+# 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.
+
+inc_etnaviv_tests = [inc_root, inc_drm, include_directories('../../etnaviv')]
+
+etnaviv_2d_test = executable(
+ 'etnaviv_2d_test',
+ files('etnaviv_2d_test.c', 'write_bmp.c'),
+ include_directories : inc_etnaviv_tests,
+ link_with : [libdrm, libdrm_etnaviv],
+ install : with_install_tests,
+)
+
+etnaviv_cmd_stream_test = executable(
+ 'etnaviv_cmd_stream_test',
+ files('etnaviv_cmd_stream_test.c'),
+ include_directories : inc_etnaviv_tests,
+ link_with : [libdrm, libdrm_etnaviv],
+ install : with_install_tests,
+)
+
+etnaviv_bo_cache_test = executable(
+ 'etnaviv_bo_cache_test',
+ files('etnaviv_bo_cache_test.c'),
+ include_directories : inc_etnaviv_tests,
+ link_with : [libdrm, libdrm_etnaviv],
+ install : with_install_tests,
+)
diff --git a/tests/etnaviv/write_bmp.c b/tests/etnaviv/write_bmp.c
index 7ae0646c..f7b6bc69 100644
--- a/tests/etnaviv/write_bmp.c
+++ b/tests/etnaviv/write_bmp.c
@@ -63,7 +63,7 @@ struct dib_header {
unsigned int unused[12];
} __attribute__((__packed__));
-static int
+static void
bmp_header_write(int fd, int width, int height, int bgra, int noflip, int alpha)
{
struct bmp_header bmp_header = {
@@ -98,8 +98,6 @@ bmp_header_write(int fd, int width, int height, int bgra, int noflip, int alpha)
write(fd, &bmp_header, sizeof(struct bmp_header));
write(fd, &dib_header, sizeof(struct dib_header));
-
- return 0;
}
void
diff --git a/tests/exynos/Makefile.am b/tests/exynos/Makefile.am
index b6361727..9658fb42 100644
--- a/tests/exynos/Makefile.am
+++ b/tests/exynos/Makefile.am
@@ -1,6 +1,7 @@
AM_CFLAGS = \
-pthread \
$(WARN_CFLAGS)\
+ -fvisibility=hidden \
-I $(top_srcdir)/include/drm \
-I $(top_srcdir)/libkms/ \
-I $(top_srcdir)/exynos \
diff --git a/tests/exynos/exynos_fimg2d_event.c b/tests/exynos/exynos_fimg2d_event.c
index 9ed5a307..353e087b 100644
--- a/tests/exynos/exynos_fimg2d_event.c
+++ b/tests/exynos/exynos_fimg2d_event.c
@@ -1,17 +1,24 @@
/*
* Copyright (C) 2015 - Tobias Jakobi
*
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
+ * 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:
*
- * It is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with it. If not, see <http://www.gnu.org/licenses/>.
+ * 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
+ * VA LINUX SYSTEMS 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 <unistd.h>
diff --git a/tests/exynos/exynos_fimg2d_perf.c b/tests/exynos/exynos_fimg2d_perf.c
index 1699bba7..97691a71 100644
--- a/tests/exynos/exynos_fimg2d_perf.c
+++ b/tests/exynos/exynos_fimg2d_perf.c
@@ -1,17 +1,24 @@
/*
* Copyright (C) 2015 - Tobias Jakobi
*
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 2 of the License,
- * or (at your option) any later version.
+ * 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:
*
- * It is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with it. If not, see <http://www.gnu.org/licenses/>.
+ * 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
+ * VA LINUX SYSTEMS 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 <stdlib.h>
@@ -267,13 +274,6 @@ int main(int argc, char **argv)
goto out;
}
- if (bufw == 0 || bufh == 0) {
- fprintf(stderr, "error: buffer width/height should be non-zero.\n");
- ret = -1;
-
- goto out;
- }
-
fd = drmOpen("exynos", NULL);
if (fd < 0) {
fprintf(stderr, "error: failed to open drm\n");
diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c
index 797fb6eb..99bb9233 100644
--- a/tests/exynos/exynos_fimg2d_test.c
+++ b/tests/exynos/exynos_fimg2d_test.c
@@ -3,17 +3,26 @@
* Authors:
* Inki Dae <inki.dae@samsung.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * 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
+ * VA LINUX SYSTEMS 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 HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -59,7 +68,6 @@ static void connector_find_mode(int fd, struct connector *c,
if (!connector) {
fprintf(stderr, "could not get connector %i: %s\n",
resources->connectors[i], strerror(errno));
- drmModeFreeConnector(connector);
continue;
}
@@ -98,7 +106,6 @@ static void connector_find_mode(int fd, struct connector *c,
if (!c->encoder) {
fprintf(stderr, "could not get encoder %i: %s\n",
resources->encoders[i], strerror(errno));
- drmModeFreeEncoder(c->encoder);
continue;
}
@@ -264,7 +271,8 @@ static int g2d_copy_test(struct exynos_device *dev, struct exynos_bo *src,
userptr = (unsigned long)malloc(size);
if (!userptr) {
fprintf(stderr, "failed to allocate userptr.\n");
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
src_img.user_ptr[0].userptr = userptr;
@@ -469,7 +477,8 @@ static int g2d_copy_with_scale_test(struct exynos_device *dev,
userptr = (unsigned long)malloc(size);
if (!userptr) {
fprintf(stderr, "failed to allocate userptr.\n");
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
src_img.user_ptr[0].userptr = userptr;
@@ -520,9 +529,10 @@ err_free_userptr:
fail:
g2d_fini(ctx);
- return 0;
+ return ret;
}
+#ifdef EXYNOS_G2D_USERPTR_TEST
static int g2d_blend_test(struct exynos_device *dev,
struct exynos_bo *src,
struct exynos_bo *dst,
@@ -557,7 +567,8 @@ static int g2d_blend_test(struct exynos_device *dev,
userptr = (unsigned long)malloc(size);
if (!userptr) {
fprintf(stderr, "failed to allocate userptr.\n");
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
src_img.user_ptr[0].userptr = userptr;
@@ -619,8 +630,9 @@ err_free_userptr:
fail:
g2d_fini(ctx);
- return 0;
+ return ret;
}
+#endif
static int g2d_checkerboard_test(struct exynos_device *dev,
struct exynos_bo *src,
@@ -645,8 +657,8 @@ static int g2d_checkerboard_test(struct exynos_device *dev,
dst_y = 0;
checkerboard = create_checkerboard_pattern(screen_width / 32, screen_height / 32, 32);
- if (checkerboard == NULL) {
- ret = -1;
+ if (!checkerboard) {
+ ret = -EFAULT;
goto fail;
}
@@ -755,8 +767,8 @@ int main(int argc, char **argv)
dev = exynos_device_create(fd);
if (!dev) {
- drmClose(dev->fd);
- return -EFAULT;
+ ret = -EFAULT;
+ goto err_drm_close;
}
resources = drmModeGetResources(dev->fd);
@@ -764,7 +776,7 @@ int main(int argc, char **argv)
fprintf(stderr, "drmModeGetResources failed: %s\n",
strerror(errno));
ret = -EFAULT;
- goto err_drm_close;
+ goto err_dev_destory;
}
connector_find_mode(dev->fd, &con, resources);
@@ -773,7 +785,7 @@ int main(int argc, char **argv)
if (!con.mode) {
fprintf(stderr, "failed to find usable connector\n");
ret = -EFAULT;
- goto err_drm_close;
+ goto err_dev_destory;
}
screen_width = con.mode->hdisplay;
@@ -782,7 +794,7 @@ int main(int argc, char **argv)
if (screen_width == 0 || screen_height == 0) {
fprintf(stderr, "failed to find sane resolution on connector\n");
ret = -EFAULT;
- goto err_drm_close;
+ goto err_dev_destory;
}
printf("screen width = %d, screen height = %d\n", screen_width,
@@ -791,7 +803,7 @@ int main(int argc, char **argv)
bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
if (!bo) {
ret = -EFAULT;
- goto err_drm_close;
+ goto err_dev_destory;
}
handles[0] = bo->handle;
@@ -864,7 +876,7 @@ int main(int argc, char **argv)
*
* Disable the test for now, until the kernel code has been sanitized.
*/
-#if 0
+#ifdef EXYNOS_G2D_USERPTR_TEST
ret = g2d_blend_test(dev, src, bo, G2D_IMGBUF_USERPTR);
if (ret < 0)
fprintf(stderr, "failed to test blend operation.\n");
@@ -882,9 +894,11 @@ err_rm_fb:
err_destroy_buffer:
exynos_destroy_buffer(bo);
-err_drm_close:
- drmClose(dev->fd);
+err_dev_destory:
exynos_device_destroy(dev);
- return 0;
+err_drm_close:
+ drmClose(fd);
+
+ return ret;
}
diff --git a/tests/exynos/meson.build b/tests/exynos/meson.build
new file mode 100644
index 00000000..3a048e8a
--- /dev/null
+++ b/tests/exynos/meson.build
@@ -0,0 +1,54 @@
+# 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.
+
+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_perf = executable(
+ 'exynos_fimg2d_perf',
+ files('exynos_fimg2d_perf.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_event = executable(
+ 'exynos_fimg2d_event',
+ files('exynos_fimg2d_event.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,
+)
diff --git a/tests/kms/Makefile.am b/tests/kms/Makefile.am
index 6645af7a..42242006 100644
--- a/tests/kms/Makefile.am
+++ b/tests/kms/Makefile.am
@@ -4,7 +4,8 @@ AM_CPPFLAGS = \
-I$(top_srcdir)
AM_CFLAGS = \
- $(WARN_CFLAGS)
+ $(WARN_CFLAGS) \
+ -fvisibility=hidden
noinst_LTLIBRARIES = libkms-test.la
diff --git a/tests/kms/kms-steal-crtc.c b/tests/kms/kms-steal-crtc.c
index 4b830d27..cd40758d 100644
--- a/tests/kms/kms-steal-crtc.c
+++ b/tests/kms/kms-steal-crtc.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
diff --git a/tests/kms/kms-universal-planes.c b/tests/kms/kms-universal-planes.c
index 89057bb5..2163c987 100644
--- a/tests/kms/kms-universal-planes.c
+++ b/tests/kms/kms-universal-planes.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <fcntl.h>
#include <getopt.h>
#include <stdbool.h>
diff --git a/tests/kms/libkms-test-crtc.c b/tests/kms/libkms-test-crtc.c
index 3adb4903..2c28face 100644
--- a/tests/kms/libkms-test-crtc.c
+++ b/tests/kms/libkms-test-crtc.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "libkms-test.h"
struct kms_crtc *kms_crtc_create(struct kms_device *device, uint32_t id)
diff --git a/tests/kms/libkms-test-device.c b/tests/kms/libkms-test-device.c
index 53c7349b..d3bb11ce 100644
--- a/tests/kms/libkms-test-device.c
+++ b/tests/kms/libkms-test-device.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -67,7 +63,7 @@ static void kms_device_probe_screens(struct kms_device *device)
device->screens = calloc(res->count_connectors, sizeof(screen));
if (!device->screens)
- return;
+ goto err_free_resources;
for (i = 0; i < res->count_connectors; i++) {
unsigned int *count;
@@ -97,6 +93,7 @@ static void kms_device_probe_screens(struct kms_device *device)
device->num_screens++;
}
+err_free_resources:
drmModeFreeResources(res);
}
@@ -112,7 +109,7 @@ static void kms_device_probe_crtcs(struct kms_device *device)
device->crtcs = calloc(res->count_crtcs, sizeof(crtc));
if (!device->crtcs)
- return;
+ goto err_free_resources;
for (i = 0; i < res->count_crtcs; i++) {
crtc = kms_crtc_create(device, res->crtcs[i]);
@@ -123,6 +120,7 @@ static void kms_device_probe_crtcs(struct kms_device *device)
device->num_crtcs++;
}
+err_free_resources:
drmModeFreeResources(res);
}
@@ -138,7 +136,7 @@ static void kms_device_probe_planes(struct kms_device *device)
device->planes = calloc(res->count_planes, sizeof(plane));
if (!device->planes)
- return;
+ goto err_free_resources;
for (i = 0; i < res->count_planes; i++) {
plane = kms_plane_create(device, res->planes[i]);
@@ -149,6 +147,7 @@ static void kms_device_probe_planes(struct kms_device *device)
device->num_planes++;
}
+err_free_resources:
drmModeFreePlaneResources(res);
}
diff --git a/tests/kms/libkms-test-framebuffer.c b/tests/kms/libkms-test-framebuffer.c
index c9e5ad3c..9bb2d95b 100644
--- a/tests/kms/libkms-test-framebuffer.c
+++ b/tests/kms/libkms-test-framebuffer.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <string.h>
diff --git a/tests/kms/libkms-test-plane.c b/tests/kms/libkms-test-plane.c
index 8eb78af1..6c40a3c9 100644
--- a/tests/kms/libkms-test-plane.c
+++ b/tests/kms/libkms-test-plane.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <string.h>
diff --git a/tests/kms/libkms-test-screen.c b/tests/kms/libkms-test-screen.c
index 33690222..bbe972a0 100644
--- a/tests/kms/libkms-test-screen.c
+++ b/tests/kms/libkms-test-screen.c
@@ -21,10 +21,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <string.h>
diff --git a/tests/kms/meson.build b/tests/kms/meson.build
new file mode 100644
index 00000000..91371aa0
--- /dev/null
+++ b/tests/kms/meson.build
@@ -0,0 +1,49 @@
+# 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 --git a/tests/kmstest/Makefile.am b/tests/kmstest/Makefile.am
index ced541b7..4c993b04 100644
--- a/tests/kmstest/Makefile.am
+++ b/tests/kmstest/Makefile.am
@@ -1,5 +1,6 @@
AM_CFLAGS = \
$(WARN_CFLAGS)\
+ -fvisibility=hidden \
-I$(top_srcdir)/include/drm \
-I$(top_srcdir)/libkms/ \
-I$(top_srcdir)/tests/ \
diff --git a/tests/kmstest/meson.build b/tests/kmstest/meson.build
new file mode 100644
index 00000000..4fb870f9
--- /dev/null
+++ b/tests/kmstest/meson.build
@@ -0,0 +1,30 @@
+# 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 --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 00000000..6c8ddd9c
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,86 @@
+# 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.
+
+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
+if with_amdgpu
+ subdir('amdgpu')
+endif
+if with_exynos
+ subdir('exynos')
+endif
+if with_tegra
+ subdir('tegra')
+endif
+if with_etnaviv
+ subdir('etnaviv')
+endif
+if with_nouveau
+ subdir('nouveau')
+endif
+
+drmsl = executable(
+ 'drmsl',
+ files('drmsl.c'),
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ c_args : libdrm_c_args,
+)
+
+hash = executable(
+ 'hash',
+ files('hash.c'),
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ c_args : libdrm_c_args,
+)
+
+random = executable(
+ 'random',
+ files('random.c'),
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ c_args : libdrm_c_args,
+)
+
+drmdevice = executable(
+ 'drmdevice',
+ files('drmdevice.c'),
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ c_args : libdrm_c_args,
+)
+
+test('random', random, timeout : 240)
+test('hash', hash)
+test('drmsl', drmsl)
+test('drmdevice', drmdevice)
diff --git a/tests/modeprint/Makefile.am b/tests/modeprint/Makefile.am
index 601dbc96..568185f0 100644
--- a/tests/modeprint/Makefile.am
+++ b/tests/modeprint/Makefile.am
@@ -1,5 +1,6 @@
AM_CFLAGS = \
$(WARN_CFLAGS)\
+ -fvisibility=hidden \
-I$(top_srcdir)/include/drm \
-I$(top_srcdir)/tests \
-I$(top_srcdir)
@@ -15,4 +16,5 @@ endif
modeprint_SOURCES = \
modeprint.c
modeprint_LDADD = \
+ $(top_builddir)/tests/util/libutil.la \
$(top_builddir)/libdrm.la
diff --git a/tests/modeprint/meson.build b/tests/modeprint/meson.build
new file mode 100644
index 00000000..0801808a
--- /dev/null
+++ b/tests/modeprint/meson.build
@@ -0,0 +1,29 @@
+# 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.
+
+modeprint = executable(
+ 'modeprint',
+ files('modeprint.c'),
+ c_args : libdrm_c_args,
+ include_directories : [inc_root, inc_tests, inc_drm],
+ link_with : [libdrm, libutil],
+ dependencies : dep_threads,
+ install : with_install_tests,
+)
diff --git a/tests/modeprint/modeprint.c b/tests/modeprint/modeprint.c
index 0d854103..ad727e12 100644
--- a/tests/modeprint/modeprint.c
+++ b/tests/modeprint/modeprint.c
@@ -42,6 +42,7 @@
#include "xf86drmMode.h"
#include "util/common.h"
+#include "util/kms.h"
int current;
int connectors;
@@ -54,20 +55,6 @@ int crtcs;
int fbs;
char *module_name;
-static const char* getConnectionText(drmModeConnection conn)
-{
- switch (conn) {
- case DRM_MODE_CONNECTED:
- return "connected";
- case DRM_MODE_DISCONNECTED:
- return "disconnected";
- case DRM_MODE_UNKNOWNCONNECTION:
- default:
- return "unknown";
- }
-
-}
-
static int printMode(struct drm_mode_modeinfo *mode)
{
if (full_modes) {
@@ -141,40 +128,24 @@ static int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, ui
return 0;
}
-static const char * const output_names[] = { "None",
- "VGA",
- "DVI-I",
- "DVI-D",
- "DVI-A",
- "Composite",
- "SVIDEO",
- "LVDS",
- "Component",
- "DIN",
- "DP",
- "HDMI-A",
- "HDMI-B",
- "TV",
- "eDP",
- "Virtual",
- "DSI",
-};
-
static int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uint32_t id)
{
int i = 0;
struct drm_mode_modeinfo *mode = NULL;
drmModePropertyPtr props;
+ const char *connector_type_name = NULL;
+
+ connector_type_name = util_lookup_connector_type_name(connector->connector_type);
- if (connector->connector_type < ARRAY_SIZE(output_names))
- printf("Connector: %s-%d\n", output_names[connector->connector_type],
+ if (connector_type_name)
+ printf("Connector: %s-%d\n", connector_type_name,
connector->connector_type_id);
else
printf("Connector: %d-%d\n", connector->connector_type,
connector->connector_type_id);
printf("\tid : %i\n", id);
printf("\tencoder id : %i\n", connector->encoder_id);
- printf("\tconn : %s\n", getConnectionText(connector->connection));
+ printf("\tconn : %s\n", util_lookup_connector_status_name(connector->connection));
printf("\tsize : %ix%i (mm)\n", connector->mmWidth, connector->mmHeight);
printf("\tcount_modes : %i\n", connector->count_modes);
printf("\tcount_props : %i\n", connector->count_props);
@@ -215,7 +186,13 @@ static int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connect
static int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t id)
{
- printf("Encoder\n");
+ const char *encoder_name;
+
+ encoder_name = util_lookup_encoder_type_name(encoder->encoder_type);
+ if (encoder_name)
+ printf("Encoder: %s\n", encoder_name);
+ else
+ printf("Encoder\n");
printf("\tid :%i\n", id);
printf("\tcrtc_id :%d\n", encoder->crtc_id);
printf("\ttype :%d\n", encoder->encoder_type);
@@ -244,7 +221,7 @@ static int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb)
printf("\thandle : %i\n", fb->handle);
printf("\twidth : %i\n", fb->width);
printf("\theight : %i\n", fb->height);
- printf("\tpitch : %i\n", fb->pitch);;
+ printf("\tpitch : %i\n", fb->pitch);
printf("\tbpp : %i\n", fb->bpp);
printf("\tdepth : %i\n", fb->depth);
printf("\tbuffer_id : %i\n", fb->handle);
diff --git a/tests/modetest/Makefile.am b/tests/modetest/Makefile.am
index 4b296c83..5eebd960 100644
--- a/tests/modetest/Makefile.am
+++ b/tests/modetest/Makefile.am
@@ -3,6 +3,7 @@ include Makefile.sources
AM_CFLAGS = $(filter-out -Wpointer-arith, $(WARN_CFLAGS))
AM_CFLAGS += \
+ -fvisibility=hidden \
-pthread \
-I$(top_srcdir)/include/drm \
-I$(top_srcdir)/tests \
diff --git a/tests/modetest/buffers.c b/tests/modetest/buffers.c
index 4fd310b9..9b635c0c 100644
--- a/tests/modetest/buffers.c
+++ b/tests/modetest/buffers.c
@@ -24,10 +24,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <assert.h>
#include <errno.h>
#include <stdio.h>
diff --git a/tests/modetest/cursor.c b/tests/modetest/cursor.c
index 6de82a4a..829bced1 100644
--- a/tests/modetest/cursor.c
+++ b/tests/modetest/cursor.c
@@ -22,10 +22,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <assert.h>
#include <errno.h>
#include <stdio.h>
diff --git a/tests/modetest/meson.build b/tests/modetest/meson.build
new file mode 100644
index 00000000..23d84a1d
--- /dev/null
+++ b/tests/modetest/meson.build
@@ -0,0 +1,29 @@
+# Copyright © 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.
+
+modetest = executable(
+ 'modetest',
+ files('buffers.c', 'cursor.c', 'modetest.c'),
+ c_args : [libdrm_c_args, '-Wno-pointer-arith'],
+ include_directories : [inc_root, inc_tests, inc_drm],
+ dependencies : [dep_threads, dep_cairo],
+ link_with : [libdrm, libutil],
+ install : with_install_tests,
+)
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index cd911193..975dcbcd 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -38,10 +38,6 @@
* the mode has been programmed, along with possible test patterns.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <assert.h>
#include <ctype.h>
#include <stdbool.h>
@@ -123,6 +119,9 @@ struct device {
struct bo *bo;
struct bo *cursor_bo;
} mode;
+
+ int use_atomic;
+ drmModeAtomicReq *req;
};
static inline int64_t U642I64(uint64_t val)
@@ -174,6 +173,15 @@ static const char *mode_flag_names[] = {
static bit_name_fn(mode_flag)
+static void dump_fourcc(uint32_t fourcc)
+{
+ printf(" %c%c%c%c",
+ fourcc,
+ fourcc >> 8,
+ fourcc >> 16,
+ fourcc >> 24);
+}
+
static void dump_encoders(struct device *dev)
{
drmModeEncoder *encoder;
@@ -242,6 +250,89 @@ static void dump_blob(struct device *dev, uint32_t blob_id)
drmModeFreePropertyBlob(blob);
}
+static const char *modifier_to_string(uint64_t modifier)
+{
+ switch (modifier) {
+ case DRM_FORMAT_MOD_INVALID:
+ return "INVALID";
+ case DRM_FORMAT_MOD_LINEAR:
+ return "LINEAR";
+ case I915_FORMAT_MOD_X_TILED:
+ return "X_TILED";
+ case I915_FORMAT_MOD_Y_TILED:
+ return "Y_TILED";
+ case I915_FORMAT_MOD_Yf_TILED:
+ return "Yf_TILED";
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ return "Y_TILED_CCS";
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ return "Yf_TILED_CCS";
+ case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
+ return "SAMSUNG_64_32_TILE";
+ case DRM_FORMAT_MOD_VIVANTE_TILED:
+ return "VIVANTE_TILED";
+ case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+ return "VIVANTE_SUPER_TILED";
+ case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED:
+ return "VIVANTE_SPLIT_TILED";
+ case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED:
+ return "VIVANTE_SPLIT_SUPER_TILED";
+ case DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED:
+ return "NVIDIA_TEGRA_TILED";
+ case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0):
+ return "NVIDIA_16BX2_BLOCK(0)";
+ case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1):
+ return "NVIDIA_16BX2_BLOCK(1)";
+ case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2):
+ return "NVIDIA_16BX2_BLOCK(2)";
+ case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3):
+ return "NVIDIA_16BX2_BLOCK(3)";
+ case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4):
+ return "NVIDIA_16BX2_BLOCK(4)";
+ case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5):
+ return "NVIDIA_16BX2_BLOCK(5)";
+ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
+ return "MOD_BROADCOM_VC4_T_TILED";
+ default:
+ return "(UNKNOWN MODIFIER)";
+ }
+}
+
+static void dump_in_formats(struct device *dev, uint32_t blob_id)
+{
+ uint32_t i, j;
+ drmModePropertyBlobPtr blob;
+ struct drm_format_modifier_blob *header;
+ uint32_t *formats;
+ struct drm_format_modifier *modifiers;
+
+ printf("\t\tin_formats blob decoded:\n");
+ blob = drmModeGetPropertyBlob(dev->fd, blob_id);
+ if (!blob) {
+ printf("\n");
+ return;
+ }
+
+ header = blob->data;
+ formats = (uint32_t *) ((char *) header + header->formats_offset);
+ modifiers = (struct drm_format_modifier *)
+ ((char *) header + header->modifiers_offset);
+
+ for (i = 0; i < header->count_formats; i++) {
+ printf("\t\t\t");
+ dump_fourcc(formats[i]);
+ printf(": ");
+ for (j = 0; j < header->count_modifiers; j++) {
+ uint64_t mask = 1ULL << i;
+ if (modifiers[j].formats & mask)
+ printf(" %s", modifier_to_string(modifiers[j].modifier));
+ }
+ printf("\n");
+ }
+
+ drmModeFreePropertyBlob(blob);
+}
+
static void dump_prop(struct device *dev, drmModePropertyPtr prop,
uint32_t prop_id, uint64_t value)
{
@@ -319,6 +410,9 @@ static void dump_prop(struct device *dev, drmModePropertyPtr prop,
printf(" %"PRId64"\n", value);
else
printf(" %"PRIu64"\n", value);
+
+ if (strcmp(prop->name, "IN_FORMATS") == 0)
+ dump_in_formats(dev, value);
}
static void dump_connectors(struct device *dev)
@@ -443,7 +537,7 @@ static void dump_planes(struct device *dev)
printf(" formats:");
for (j = 0; j < ovr->count_formats; j++)
- printf(" %4.4s", (char *)&ovr->formats[j]);
+ dump_fourcc(ovr->formats[j]);
printf("\n");
if (plane->props) {
@@ -524,7 +618,6 @@ static struct resources *get_resources(struct device *dev)
return NULL;
drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
- drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1);
res->res = drmModeGetResources(dev->fd);
if (!res->res) {
@@ -562,10 +655,13 @@ static struct resources *get_resources(struct device *dev)
for (i = 0; i < res->res->count_connectors; i++) {
struct connector *connector = &res->connectors[i];
drmModeConnector *conn = connector->connector;
+ int num;
- asprintf(&connector->name, "%s-%u",
+ num = asprintf(&connector->name, "%s-%u",
util_lookup_connector_type_name(conn->connector_type),
conn->connector_type_id);
+ if (num < 0)
+ goto error;
}
#define get_properties(_res, __res, type, Type) \
@@ -712,7 +808,9 @@ struct plane_arg {
uint32_t w, h;
double scale;
unsigned int fb_id;
+ unsigned int old_fb_id;
struct bo *bo;
+ struct bo *old_bo;
char format_str[5]; /* need to leave room for terminating \0 */
unsigned int fourcc;
};
@@ -906,8 +1004,12 @@ static void set_property(struct device *dev, struct property_arg *p)
p->prop_id = props->props[i];
- ret = drmModeObjectSetProperty(dev->fd, p->obj_id, p->obj_type,
- p->prop_id, p->value);
+ if (!dev->use_atomic)
+ ret = drmModeObjectSetProperty(dev->fd, p->obj_id, p->obj_type,
+ p->prop_id, p->value);
+ else
+ ret = drmModeAtomicAddProperty(dev->req, p->obj_id, p->prop_id, p->value);
+
if (ret < 0)
fprintf(stderr, "failed to set %s %i property %s to %" PRIu64 ": %s\n",
obj_type, p->obj_id, p->name, p->value, strerror(errno));
@@ -956,6 +1058,94 @@ static bool format_support(const drmModePlanePtr ovr, uint32_t fmt)
return false;
}
+static void add_property(struct device *dev, uint32_t obj_id,
+ const char *name, uint64_t value)
+{
+ struct property_arg p;
+
+ p.obj_id = obj_id;
+ strcpy(p.name, name);
+ p.value = value;
+
+ set_property(dev, &p);
+}
+
+static int atomic_set_plane(struct device *dev, struct plane_arg *p,
+ int pattern, bool update)
+{
+ uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
+ struct bo *plane_bo;
+ int crtc_x, crtc_y, crtc_w, crtc_h;
+ struct crtc *crtc = NULL;
+ unsigned int i;
+ unsigned int old_fb_id;
+
+ /* Find an unused plane which can be connected to our CRTC. Find the
+ * CRTC index first, then iterate over available planes.
+ */
+ for (i = 0; i < (unsigned int)dev->resources->res->count_crtcs; i++) {
+ if (p->crtc_id == dev->resources->res->crtcs[i]) {
+ crtc = &dev->resources->crtcs[i];
+ break;
+ }
+ }
+
+ if (!crtc) {
+ fprintf(stderr, "CRTC %u not found\n", p->crtc_id);
+ return -1;
+ }
+
+ if (!update)
+ fprintf(stderr, "testing %dx%d@%s on plane %u, crtc %u\n",
+ p->w, p->h, p->format_str, p->plane_id, p->crtc_id);
+
+ plane_bo = p->old_bo;
+ p->old_bo = p->bo;
+
+ if (!plane_bo) {
+ plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h,
+ handles, pitches, offsets, pattern);
+
+ if (plane_bo == NULL)
+ return -1;
+
+ if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc,
+ handles, pitches, offsets, &p->fb_id, 0)) {
+ fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
+ return -1;
+ }
+ }
+
+ p->bo = plane_bo;
+
+ old_fb_id = p->fb_id;
+ p->old_fb_id = old_fb_id;
+
+ crtc_w = p->w * p->scale;
+ crtc_h = p->h * p->scale;
+ if (!p->has_position) {
+ /* Default to the middle of the screen */
+ crtc_x = (crtc->mode->hdisplay - crtc_w) / 2;
+ crtc_y = (crtc->mode->vdisplay - crtc_h) / 2;
+ } else {
+ crtc_x = p->x;
+ crtc_y = p->y;
+ }
+
+ add_property(dev, p->plane_id, "FB_ID", p->fb_id);
+ add_property(dev, p->plane_id, "CRTC_ID", p->crtc_id);
+ add_property(dev, p->plane_id, "SRC_X", 0);
+ add_property(dev, p->plane_id, "SRC_Y", 0);
+ add_property(dev, p->plane_id, "SRC_W", p->w << 16);
+ add_property(dev, p->plane_id, "SRC_H", p->h << 16);
+ add_property(dev, p->plane_id, "CRTC_X", crtc_x);
+ add_property(dev, p->plane_id, "CRTC_Y", crtc_y);
+ add_property(dev, p->plane_id, "CRTC_W", crtc_w);
+ add_property(dev, p->plane_id, "CRTC_H", crtc_h);
+
+ return 0;
+}
+
static int set_plane(struct device *dev, struct plane_arg *p)
{
drmModePlane *ovr;
@@ -997,7 +1187,8 @@ static int set_plane(struct device *dev, struct plane_arg *p)
if (!format_support(ovr, p->fourcc))
continue;
- if ((ovr->possible_crtcs & (1 << pipe)) && !ovr->crtc_id) {
+ if ((ovr->possible_crtcs & (1 << pipe)) &&
+ (ovr->crtc_id == 0 || ovr->crtc_id == p->crtc_id)) {
plane_id = ovr->plane_id;
break;
}
@@ -1051,6 +1242,64 @@ static int set_plane(struct device *dev, struct plane_arg *p)
return 0;
}
+static void atomic_set_planes(struct device *dev, struct plane_arg *p,
+ unsigned int count, bool update)
+{
+ unsigned int i, pattern = UTIL_PATTERN_SMPTE;
+
+ /* set up planes */
+ for (i = 0; i < count; i++) {
+ if (i > 0)
+ pattern = UTIL_PATTERN_TILES;
+
+ if (atomic_set_plane(dev, &p[i], pattern, update))
+ return;
+ }
+}
+
+static void atomic_clear_planes(struct device *dev, struct plane_arg *p, unsigned int count)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++) {
+ add_property(dev, p[i].plane_id, "FB_ID", 0);
+ add_property(dev, p[i].plane_id, "CRTC_ID", 0);
+ add_property(dev, p[i].plane_id, "SRC_X", 0);
+ add_property(dev, p[i].plane_id, "SRC_Y", 0);
+ add_property(dev, p[i].plane_id, "SRC_W", 0);
+ add_property(dev, p[i].plane_id, "SRC_H", 0);
+ add_property(dev, p[i].plane_id, "CRTC_X", 0);
+ add_property(dev, p[i].plane_id, "CRTC_Y", 0);
+ add_property(dev, p[i].plane_id, "CRTC_W", 0);
+ add_property(dev, p[i].plane_id, "CRTC_H", 0);
+ }
+}
+
+static void atomic_clear_FB(struct device *dev, struct plane_arg *p, unsigned int count)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++) {
+ if (p[i].fb_id) {
+ drmModeRmFB(dev->fd, p[i].fb_id);
+ p[i].fb_id = 0;
+ }
+ if (p[i].old_fb_id) {
+ drmModeRmFB(dev->fd, p[i].old_fb_id);
+ p[i].old_fb_id = 0;
+ }
+ if (p[i].bo) {
+ bo_destroy(p[i].bo);
+ p[i].bo = NULL;
+ }
+ if (p[i].old_bo) {
+ bo_destroy(p[i].old_bo);
+ p[i].old_bo = NULL;
+ }
+
+ }
+}
+
static void clear_planes(struct device *dev, struct plane_arg *p, unsigned int count)
{
unsigned int i;
@@ -1063,6 +1312,59 @@ static void clear_planes(struct device *dev, struct plane_arg *p, unsigned int c
}
}
+static void atomic_set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
+{
+ unsigned int i;
+ unsigned int j;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ struct pipe_arg *pipe = &pipes[i];
+
+ ret = pipe_find_crtc_and_mode(dev, pipe);
+ if (ret < 0)
+ continue;
+ }
+
+ for (i = 0; i < count; i++) {
+ struct pipe_arg *pipe = &pipes[i];
+ uint32_t blob_id;
+
+ if (pipe->mode == NULL)
+ continue;
+
+ printf("setting mode %s-%dHz@%s on connectors ",
+ pipe->mode_str, pipe->mode->vrefresh, pipe->format_str);
+ for (j = 0; j < pipe->num_cons; ++j) {
+ printf("%s, ", pipe->cons[j]);
+ add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc->crtc->crtc_id);
+ }
+ printf("crtc %d\n", pipe->crtc->crtc->crtc_id);
+
+ drmModeCreatePropertyBlob(dev->fd, pipe->mode, sizeof(*pipe->mode), &blob_id);
+ add_property(dev, pipe->crtc->crtc->crtc_id, "MODE_ID", blob_id);
+ add_property(dev, pipe->crtc->crtc->crtc_id, "ACTIVE", 1);
+ }
+}
+
+static void atomic_clear_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
+{
+ unsigned int i;
+ unsigned int j;
+
+ for (i = 0; i < count; i++) {
+ struct pipe_arg *pipe = &pipes[i];
+
+ if (pipe->mode == NULL)
+ continue;
+
+ for (j = 0; j < pipe->num_cons; ++j)
+ add_property(dev, pipe->con_ids[j], "CRTC_ID",0);
+
+ add_property(dev, pipe->crtc->crtc->crtc_id, "MODE_ID", 0);
+ add_property(dev, pipe->crtc->crtc->crtc_id, "ACTIVE", 0);
+ }
+}
static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
{
@@ -1438,7 +1740,7 @@ static int parse_property(struct property_arg *p, const char *arg)
static void usage(char *name)
{
- fprintf(stderr, "usage: %s [-cDdefMPpsCvw]\n", name);
+ fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
fprintf(stderr, "\n Query options:\n\n");
fprintf(stderr, "\t-c\tlist connectors\n");
@@ -1452,6 +1754,7 @@ static void usage(char *name)
fprintf(stderr, "\t-C\ttest hw cursor\n");
fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
+ fprintf(stderr, "\t-a \tuse atomic API\n");
fprintf(stderr, "\n Generic options:\n\n");
fprintf(stderr, "\t-d\tdrop master after mode set\n");
@@ -1515,7 +1818,7 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
return 0;
}
-static char optstr[] = "cdD:efM:P:ps:Cvw:";
+static char optstr[] = "acdD:efM:P:ps:Cvw:";
int main(int argc, char **argv)
{
@@ -1526,6 +1829,7 @@ int main(int argc, char **argv)
int drop_master = 0;
int test_vsync = 0;
int test_cursor = 0;
+ int use_atomic = 0;
char *device = NULL;
char *module = NULL;
unsigned int i;
@@ -1544,6 +1848,9 @@ int main(int argc, char **argv)
args++;
switch (c) {
+ case 'a':
+ use_atomic = 1;
+ break;
case 'c':
connectors = 1;
break;
@@ -1623,13 +1930,22 @@ int main(int argc, char **argv)
}
}
- if (!args)
+ if (!args || (args == 1 && use_atomic))
encoders = connectors = crtcs = planes = framebuffers = 1;
dev.fd = util_open(device, module);
if (dev.fd < 0)
return -1;
+ ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1);
+ if (ret && use_atomic) {
+ fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno));
+ drmClose(dev.fd);
+ return -1;
+ }
+
+ dev.use_atomic = use_atomic;
+
if (test_vsync && !page_flipping_supported()) {
fprintf(stderr, "page flipping not supported by drm.\n");
return -1;
@@ -1670,40 +1986,111 @@ int main(int argc, char **argv)
for (i = 0; i < prop_count; ++i)
set_property(&dev, &prop_args[i]);
- if (count || plane_count) {
- uint64_t cap = 0;
+ if (dev.use_atomic) {
+ dev.req = drmModeAtomicAlloc();
- ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap);
- if (ret || cap == 0) {
- fprintf(stderr, "driver doesn't support the dumb buffer API\n");
- return 1;
+ if (count && plane_count) {
+ uint64_t cap = 0;
+
+ ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap);
+ if (ret || cap == 0) {
+ fprintf(stderr, "driver doesn't support the dumb buffer API\n");
+ return 1;
+ }
+
+ atomic_set_mode(&dev, pipe_args, count);
+ atomic_set_planes(&dev, plane_args, plane_count, false);
+
+ ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ if (ret) {
+ fprintf(stderr, "Atomic Commit failed [1]\n");
+ return 1;
+ }
+
+ gettimeofday(&pipe_args->start, NULL);
+ pipe_args->swap_count = 0;
+
+ while (test_vsync) {
+ drmModeAtomicFree(dev.req);
+ dev.req = drmModeAtomicAlloc();
+ atomic_set_planes(&dev, plane_args, plane_count, true);
+
+ ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ if (ret) {
+ fprintf(stderr, "Atomic Commit failed [2]\n");
+ return 1;
+ }
+
+ pipe_args->swap_count++;
+ if (pipe_args->swap_count == 60) {
+ struct timeval end;
+ double t;
+
+ gettimeofday(&end, NULL);
+ t = end.tv_sec + end.tv_usec * 1e-6 -
+ (pipe_args->start.tv_sec + pipe_args->start.tv_usec * 1e-6);
+ fprintf(stderr, "freq: %.02fHz\n", pipe_args->swap_count / t);
+ pipe_args->swap_count = 0;
+ pipe_args->start = end;
+ }
+ }
+
+ if (drop_master)
+ drmDropMaster(dev.fd);
+
+ getchar();
+
+ drmModeAtomicFree(dev.req);
+ dev.req = drmModeAtomicAlloc();
+
+ atomic_clear_mode(&dev, pipe_args, count);
+ atomic_clear_planes(&dev, plane_args, plane_count);
+ ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ if (ret) {
+ fprintf(stderr, "Atomic Commit failed\n");
+ return 1;
+ }
+
+ atomic_clear_FB(&dev, plane_args, plane_count);
}
- if (count)
- set_mode(&dev, pipe_args, count);
+ drmModeAtomicFree(dev.req);
+ } else {
+ if (count || plane_count) {
+ uint64_t cap = 0;
- if (plane_count)
- set_planes(&dev, plane_args, plane_count);
+ ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap);
+ if (ret || cap == 0) {
+ fprintf(stderr, "driver doesn't support the dumb buffer API\n");
+ return 1;
+ }
+
+ if (count)
+ set_mode(&dev, pipe_args, count);
- if (test_cursor)
- set_cursors(&dev, pipe_args, count);
+ if (plane_count)
+ set_planes(&dev, plane_args, plane_count);
- if (test_vsync)
- test_page_flip(&dev, pipe_args, count);
+ if (test_cursor)
+ set_cursors(&dev, pipe_args, count);
- if (drop_master)
- drmDropMaster(dev.fd);
+ if (test_vsync)
+ test_page_flip(&dev, pipe_args, count);
- getchar();
+ if (drop_master)
+ drmDropMaster(dev.fd);
- if (test_cursor)
- clear_cursors(&dev);
+ getchar();
- if (plane_count)
- clear_planes(&dev, plane_args, plane_count);
+ if (test_cursor)
+ clear_cursors(&dev);
- if (count)
- clear_mode(&dev);
+ if (plane_count)
+ clear_planes(&dev, plane_args, plane_count);
+
+ if (count)
+ clear_mode(&dev);
+ }
}
free_resources(dev.resources);
diff --git a/tests/nouveau/Makefile.am b/tests/nouveau/Makefile.am
index 3c799a81..554f43ec 100644
--- a/tests/nouveau/Makefile.am
+++ b/tests/nouveau/Makefile.am
@@ -1,6 +1,7 @@
AM_CFLAGS = \
-pthread \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir)/include/drm \
-I$(top_srcdir)/nouveau \
-I$(top_srcdir)
diff --git a/tests/nouveau/meson.build b/tests/nouveau/meson.build
new file mode 100644
index 00000000..ca4d44f0
--- /dev/null
+++ b/tests/nouveau/meson.build
@@ -0,0 +1,30 @@
+# 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.
+
+threaded = executable(
+ 'threaded',
+ files('threaded.c'),
+ dependencies : [dep_dl, dep_threads],
+ include_directories : [inc_root, inc_drm, include_directories('../../nouveau')],
+ link_with : [libdrm, libdrm_nouveau],
+ c_args : libdrm_c_args,
+)
+
+test('threaded', threaded)
diff --git a/tests/nouveau/threaded.c b/tests/nouveau/threaded.c
index 281af460..3669bcd3 100644
--- a/tests/nouveau/threaded.c
+++ b/tests/nouveau/threaded.c
@@ -20,10 +20,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
#include <sys/ioctl.h>
#include <dlfcn.h>
#include <fcntl.h>
diff --git a/tests/planetest/Android.bp b/tests/planetest/Android.bp
deleted file mode 100644
index 16dfc5b7..00000000
--- a/tests/planetest/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-build = ["Android.sources.bp"]
-
-cc_test {
- name: "planetest",
- defaults: [
- "planetest_common_sources",
- "planetest_sources",
- ],
- shared_libs: ["libdrm"],
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- "-Wno-pointer-arith",
- ],
-}
-
-cc_test {
- name: "atomictest",
- defaults: [
- "planetest_common_sources",
- "atomictest_sources",
- ],
- shared_libs: ["libdrm"],
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- "-Wno-pointer-arith",
- ],
-}
diff --git a/tests/planetest/Android.sources.bp b/tests/planetest/Android.sources.bp
deleted file mode 100644
index 4a35bb51..00000000
--- a/tests/planetest/Android.sources.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Autogenerated with Android.sources.bp.mk
-
-cc_defaults {
- name: "planetest_common_sources",
- srcs: [
- "bo.c",
- "dev.c",
- "modeset.c",
- ],
-}
-
-cc_defaults {
- name: "planetest_sources",
- srcs: [
- "planetest.c",
- ],
-}
-
-cc_defaults {
- name: "atomictest_sources",
- srcs: [
- "atomictest.c",
- ],
-}
diff --git a/tests/planetest/Makefile.am b/tests/planetest/Makefile.am
deleted file mode 100644
index b82d05b8..00000000
--- a/tests/planetest/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-include Makefile.sources
-
-AM_CFLAGS = $(filter-out -Wpointer-arith, $(WARN_CFLAGS))
-
-AM_CFLAGS += \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/libkms/ \
- -I$(top_srcdir)
-
-PLANETEST_COMMON_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/libkms/libkms.la \
- -lpthread
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- atomictest \
- planetest
-else
-noinst_PROGRAMS = \
- atomictest \
- planetest
-endif
-
-atomictest_CFLAGS=-DUSE_ATOMIC_API ${AM_CFLAGS}
-atomictest_SOURCES=${PLANETEST_COMMON_FILES} ${ATOMICTEST_FILES}
-planetest_SOURCES=${PLANETEST_COMMON_FILES} ${PLANETEST_FILES}
-
-atomictest_LDADD=${PLANETEST_COMMON_LDADD}
-planetest_LDADD=${PLANETEST_COMMON_LDADD}
diff --git a/tests/planetest/Makefile.sources b/tests/planetest/Makefile.sources
deleted file mode 100644
index 3cbeb2b3..00000000
--- a/tests/planetest/Makefile.sources
+++ /dev/null
@@ -1,13 +0,0 @@
-PLANETEST_COMMON_FILES := \
- bo.c \
- bo.h \
- dev.c \
- dev.h \
- modeset.c \
- modeset.h
-
-ATOMICTEST_FILES := \
- atomictest.c
-
-PLANETEST_FILES := \
- planetest.c
diff --git a/tests/planetest/atomictest.c b/tests/planetest/atomictest.c
deleted file mode 100644
index 5fec911a..00000000
--- a/tests/planetest/atomictest.c
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <time.h>
-#include <errno.h>
-
-#include <xf86drm.h>
-
-#include "dev.h"
-#include "bo.h"
-#include "modeset.h"
-
-static int terminate = 0;
-
-static void sigint_handler(int arg)
-{
- terminate = 1;
-}
-
-static void
-page_flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
- unsigned int tv_usec, void *user_data)
-{
-}
-
-static void incrementor(int *inc, int *val, int increment, int lower, int upper)
-{
- if(*inc > 0)
- *inc = *val + increment >= upper ? -1 : 1;
- else
- *inc = *val - increment <= lower ? 1 : -1;
- *val += *inc * increment;
-}
-
-int main(int argc, char *argv[])
-{
- int ret, i, j, num_test_planes;
- int x_inc = 1, x = 0, y_inc = 1, y = 0;
- uint32_t plane_w = 128, plane_h = 128;
- struct sp_dev *dev;
- struct sp_plane **plane = NULL;
- struct sp_crtc *test_crtc;
- fd_set fds;
- drmModePropertySetPtr pset;
- drmEventContext event_context = {
- .version = DRM_EVENT_CONTEXT_VERSION,
- .page_flip_handler = page_flip_handler,
- };
- int card = 0, crtc = 0;
-
- signal(SIGINT, sigint_handler);
-
- parse_arguments(argc, argv, &card, &crtc);
-
- dev = create_sp_dev(card);
- if (!dev) {
- printf("Failed to create sp_dev\n");
- return -1;
- }
-
- if (crtc >= dev->num_crtcs) {
- printf("Invalid crtc %d (num=%d)\n", crtc, dev->num_crtcs);
- return -1;
- }
-
- ret = initialize_screens(dev);
- if (ret) {
- printf("Failed to initialize screens\n");
- goto out;
- }
- test_crtc = &dev->crtcs[crtc];
-
- plane = calloc(dev->num_planes, sizeof(*plane));
- if (!plane) {
- printf("Failed to allocate plane array\n");
- goto out;
- }
-
- /* Create our planes */
- num_test_planes = test_crtc->num_planes;
- for (i = 0; i < num_test_planes; i++) {
- plane[i] = get_sp_plane(dev, test_crtc);
- if (!plane[i]) {
- printf("no unused planes available\n");
- goto out;
- }
-
- plane[i]->bo = create_sp_bo(dev, plane_w, plane_h, 16, plane[i]->format, 0);
- if (!plane[i]->bo) {
- printf("failed to create plane bo\n");
- goto out;
- }
-
- fill_bo(plane[i]->bo, 0xFF, 0xFF, 0xFF, 0xFF);
- }
-
- pset = drmModePropertySetAlloc();
- if (!pset) {
- printf("Failed to allocate the property set\n");
- goto out;
- }
-
- while (!terminate) {
- FD_ZERO(&fds);
- FD_SET(dev->fd, &fds);
-
- incrementor(&x_inc, &x, 5, 0,
- test_crtc->crtc->mode.hdisplay - plane_w);
- incrementor(&y_inc, &y, 5, 0, test_crtc->crtc->mode.vdisplay -
- plane_h * num_test_planes);
-
- for (j = 0; j < num_test_planes; j++) {
- ret = set_sp_plane_pset(dev, plane[j], pset, test_crtc,
- x, y + j * plane_h);
- if (ret) {
- printf("failed to move plane %d\n", ret);
- goto out;
- }
- }
-
- ret = drmModePropertySetCommit(dev->fd,
- DRM_MODE_PAGE_FLIP_EVENT, NULL, pset);
- if (ret) {
- printf("failed to commit properties ret=%d\n", ret);
- goto out;
- }
-
- do {
- ret = select(dev->fd + 1, &fds, NULL, NULL, NULL);
- } while (ret == -1 && errno == EINTR);
-
- if (FD_ISSET(dev->fd, &fds))
- drmHandleEvent(dev->fd, &event_context);
- }
-
- drmModePropertySetFree(pset);
-
- for (i = 0; i < num_test_planes; i++)
- put_sp_plane(plane[i]);
-
-out:
- destroy_sp_dev(dev);
- free(plane);
- return ret;
-}
diff --git a/tests/planetest/bo.c b/tests/planetest/bo.c
deleted file mode 100644
index d4b82c66..00000000
--- a/tests/planetest/bo.c
+++ /dev/null
@@ -1,234 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <drm_fourcc.h>
-
-#include "bo.h"
-#include "dev.h"
-
-#define MAKE_YUV_601_Y(r, g, b) \
- ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16)
-#define MAKE_YUV_601_U(r, g, b) \
- (((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128)
-#define MAKE_YUV_601_V(r, g, b) \
- (((112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128)
-
-static void draw_rect_yuv(struct sp_bo *bo, uint32_t x, uint32_t y, uint32_t width,
- uint32_t height, uint8_t a, uint8_t r, uint8_t g, uint8_t b)
-{
- uint32_t i, j, xmax = x + width, ymax = y + height;
-
- if (xmax > bo->width)
- xmax = bo->width;
- if (ymax > bo->height)
- ymax = bo->height;
-
- for (i = y; i < ymax; i++) {
- uint8_t *luma = bo->map_addr + i * bo->pitch;
-
- for (j = x; j < xmax; j++)
- luma[j] = MAKE_YUV_601_Y(r, g, b);
- }
-
- for (i = y; i < ymax / 2; i++) {
- uint8_t *chroma = bo->map_addr + (i + height) * bo->pitch;
-
- for (j = x; j < xmax / 2; j++) {
- chroma[j*2] = MAKE_YUV_601_U(r, g, b);
- chroma[j*2 + 1] = MAKE_YUV_601_V(r, g, b);
- }
- }
-}
-
-void fill_bo(struct sp_bo *bo, uint8_t a, uint8_t r, uint8_t g, uint8_t b)
-{
- if (bo->format == DRM_FORMAT_NV12)
- draw_rect_yuv(bo, 0, 0, bo->width, bo->height, a, r, g, b);
- else
- draw_rect(bo, 0, 0, bo->width, bo->height, a, r, g, b);
-}
-
-void draw_rect(struct sp_bo *bo, uint32_t x, uint32_t y, uint32_t width,
- uint32_t height, uint8_t a, uint8_t r, uint8_t g, uint8_t b)
-{
- uint32_t i, j, xmax = x + width, ymax = y + height;
-
- if (xmax > bo->width)
- xmax = bo->width;
- if (ymax > bo->height)
- ymax = bo->height;
-
- for (i = y; i < ymax; i++) {
- uint8_t *row = bo->map_addr + i * bo->pitch;
-
- for (j = x; j < xmax; j++) {
- uint8_t *pixel = row + j * 4;
-
- if (bo->format == DRM_FORMAT_ARGB8888 ||
- bo->format == DRM_FORMAT_XRGB8888)
- {
- pixel[0] = b;
- pixel[1] = g;
- pixel[2] = r;
- pixel[3] = a;
- } else if (bo->format == DRM_FORMAT_RGBA8888) {
- pixel[0] = r;
- pixel[1] = g;
- pixel[2] = b;
- pixel[3] = a;
- }
- }
- }
-}
-
-static int add_fb_sp_bo(struct sp_bo *bo, uint32_t format)
-{
- int ret;
- uint32_t handles[4], pitches[4], offsets[4];
-
- handles[0] = bo->handle;
- pitches[0] = bo->pitch;
- offsets[0] = 0;
- if (bo->format == DRM_FORMAT_NV12) {
- handles[1] = bo->handle;
- pitches[1] = pitches[0];
- offsets[1] = pitches[0] * bo->height;
- }
-
- ret = drmModeAddFB2(bo->dev->fd, bo->width, bo->height,
- format, handles, pitches, offsets,
- &bo->fb_id, bo->flags);
- if (ret) {
- printf("failed to create fb ret=%d\n", ret);
- return ret;
- }
- return 0;
-}
-
-static int map_sp_bo(struct sp_bo *bo)
-{
- int ret;
- struct drm_mode_map_dumb md;
-
- if (bo->map_addr)
- return 0;
-
- md.handle = bo->handle;
- ret = drmIoctl(bo->dev->fd, DRM_IOCTL_MODE_MAP_DUMB, &md);
- if (ret) {
- printf("failed to map sp_bo ret=%d\n", ret);
- return ret;
- }
-
- bo->map_addr = mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
- bo->dev->fd, md.offset);
- if (bo->map_addr == MAP_FAILED) {
- printf("failed to map bo ret=%d\n", -errno);
- return -errno;
- }
- return 0;
-}
-
-static int format_to_bpp(uint32_t format)
-{
- switch (format) {
- case DRM_FORMAT_NV12:
- return 8;
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_XRGB8888:
- case DRM_FORMAT_RGBA8888:
- default:
- return 32;
- }
-}
-
-struct sp_bo *create_sp_bo(struct sp_dev *dev, uint32_t width, uint32_t height,
- uint32_t depth, uint32_t format, uint32_t flags)
-{
- int ret;
- struct drm_mode_create_dumb cd;
- struct sp_bo *bo;
-
- bo = calloc(1, sizeof(*bo));
- if (!bo)
- return NULL;
-
- if (format == DRM_FORMAT_NV12)
- cd.height = height * 3 / 2;
- else
- cd.height = height;
-
- cd.width = width;
- cd.bpp = format_to_bpp(format);
- cd.flags = flags;
-
- ret = drmIoctl(dev->fd, DRM_IOCTL_MODE_CREATE_DUMB, &cd);
- if (ret) {
- printf("failed to create sp_bo %d\n", ret);
- goto err;
- }
-
- bo->dev = dev;
- bo->width = width;
- bo->height = height;
- bo->depth = depth;
- bo->bpp = format_to_bpp(format);
- bo->format = format;
- bo->flags = flags;
-
- bo->handle = cd.handle;
- bo->pitch = cd.pitch;
- bo->size = cd.size;
-
- ret = add_fb_sp_bo(bo, format);
- if (ret) {
- printf("failed to add fb ret=%d\n", ret);
- goto err;
- }
-
- ret = map_sp_bo(bo);
- if (ret) {
- printf("failed to map bo ret=%d\n", ret);
- goto err;
- }
-
- return bo;
-
-err:
- free_sp_bo(bo);
- return NULL;
-}
-
-void free_sp_bo(struct sp_bo *bo)
-{
- int ret;
- struct drm_mode_destroy_dumb dd;
-
- if (!bo)
- return;
-
- if (bo->map_addr)
- munmap(bo->map_addr, bo->size);
-
- if (bo->fb_id) {
- ret = drmModeRmFB(bo->dev->fd, bo->fb_id);
- if (ret)
- printf("Failed to rmfb ret=%d!\n", ret);
- }
-
- if (bo->handle) {
- dd.handle = bo->handle;
- ret = drmIoctl(bo->dev->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dd);
- if (ret)
- printf("Failed to destroy buffer ret=%d\n", ret);
- }
-
- free(bo);
-}
diff --git a/tests/planetest/bo.h b/tests/planetest/bo.h
deleted file mode 100644
index 7471e126..00000000
--- a/tests/planetest/bo.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __BO_H_INCLUDED__
-#define __BO_H_INCLUDED__
-
-#include <stdint.h>
-
-struct sp_dev;
-
-struct sp_bo {
- struct sp_dev *dev;
-
- uint32_t width;
- uint32_t height;
- uint32_t depth;
- uint32_t bpp;
- uint32_t format;
- uint32_t flags;
-
- uint32_t fb_id;
- uint32_t handle;
- void *map_addr;
- uint32_t pitch;
- uint32_t size;
-};
-
-struct sp_bo *create_sp_bo(struct sp_dev *dev, uint32_t width, uint32_t height,
- uint32_t depth, uint32_t format, uint32_t flags);
-
-void fill_bo(struct sp_bo *bo, uint8_t a, uint8_t r, uint8_t g, uint8_t b);
-void draw_rect(struct sp_bo *bo, uint32_t x, uint32_t y, uint32_t width,
- uint32_t height, uint8_t a, uint8_t r, uint8_t g, uint8_t b);
-
-void free_sp_bo(struct sp_bo *bo);
-
-#endif /* __BO_H_INCLUDED__ */
diff --git a/tests/planetest/dev.c b/tests/planetest/dev.c
deleted file mode 100644
index bd0968c6..00000000
--- a/tests/planetest/dev.c
+++ /dev/null
@@ -1,367 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <getopt.h>
-
-#include <drm.h>
-#include <drm_fourcc.h>
-#include <errno.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include "bo.h"
-#include "dev.h"
-#include "modeset.h"
-
-static void show_usage(char *name)
-{
- printf("Usage: %s [OPTION]\n", name);
- printf(" -c, --card Index of dri card (ie: /dev/dri/cardN)\n");
- printf(" -r, --crtc Index of crtc to use for test\n");
- printf("\n\n");
-}
-
-void parse_arguments(int argc, char *argv[], int *card, int *crtc)
-{
- static struct option options[] = {
- { "card", required_argument, NULL, 'c' },
- { "crtc", required_argument, NULL, 'r' },
- { "help", no_argument, NULL, 'h' },
- };
- int option_index = 0;
- int c;
-
- *card = -1;
- *crtc = -1;
- do {
- c = getopt_long(argc, argv, "c:r:h", options, &option_index);
- switch (c) {
- case 0:
- case 'h':
- show_usage(argv[0]);
- exit(0);
- case -1:
- break;
- case 'c':
- if (optarg[0] < '0' || optarg[0] > '9') {
- printf("Invalid card value '%s'!\n", optarg);
- show_usage(argv[0]);
- exit(-1);
- }
- *card = optarg[0] - '0';
- break;
- case 'r':
- if (optarg[0] < '0' || optarg[0] > '9') {
- printf("Invalid crtc value '%s'!\n", optarg);
- show_usage(argv[0]);
- exit(-1);
- }
- *crtc = optarg[0] - '0';
- break;
- }
- } while (c != -1);
-
- if (*card < 0 || *crtc < 0) {
- show_usage(argv[0]);
- exit(-1);
- }
-}
-
-static uint32_t get_prop_id(struct sp_dev *dev,
- drmModeObjectPropertiesPtr props, const char *name)
-{
- drmModePropertyPtr p;
- uint32_t i, prop_id = 0; /* Property ID should always be > 0 */
-
- for (i = 0; !prop_id && i < props->count_props; i++) {
- p = drmModeGetProperty(dev->fd, props->props[i]);
- if (!strcmp(p->name, name))
- prop_id = p->prop_id;
- drmModeFreeProperty(p);
- }
- if (!prop_id)
- printf("Could not find %s property\n", name);
- return prop_id;
-}
-
-static int get_supported_format(struct sp_plane *plane, uint32_t *format)
-{
- uint32_t i;
-
- for (i = 0; i < plane->plane->count_formats; i++) {
- if (plane->plane->formats[i] == DRM_FORMAT_XRGB8888 ||
- plane->plane->formats[i] == DRM_FORMAT_ARGB8888 ||
- plane->plane->formats[i] == DRM_FORMAT_RGBA8888 ||
- plane->plane->formats[i] == DRM_FORMAT_NV12) {
- *format = plane->plane->formats[i];
- return 0;
- }
- }
- printf("No suitable formats found!\n");
- return -ENOENT;
-}
-
-struct sp_dev *create_sp_dev(int card)
-{
- struct sp_dev *dev;
- int ret, fd, i, j;
- drmModeRes *r = NULL;
- drmModePlaneRes *pr = NULL;
- char card_path[256];
-
- snprintf(card_path, sizeof(card_path), "/dev/dri/card%d", card);
-
- fd = open(card_path, O_RDWR);
- if (fd < 0) {
- printf("failed to open card0\n");
- return NULL;
- }
-
- dev = calloc(1, sizeof(*dev));
- if (!dev) {
- printf("failed to allocate dev\n");
- return NULL;
- }
-
- dev->fd = fd;
-
- ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
- if (ret) {
- printf("failed to set client cap\n");
- goto err;
- }
-
- ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1);
- if (ret) {
- printf("Failed to set atomic cap %d", ret);
- goto err;
- }
-
- r = drmModeGetResources(dev->fd);
- if (!r) {
- printf("failed to get r\n");
- goto err;
- }
-
- dev->num_connectors = r->count_connectors;
- dev->connectors = calloc(dev->num_connectors,
- sizeof(struct sp_connector));
- if (!dev->connectors) {
- printf("failed to allocate connectors\n");
- goto err;
- }
- for (i = 0; i < dev->num_connectors; i++) {
- drmModeObjectPropertiesPtr props;
- dev->connectors[i].conn = drmModeGetConnector(dev->fd,
- r->connectors[i]);
- if (!dev->connectors[i].conn) {
- printf("failed to get connector %d\n", i);
- goto err;
- }
-
- props = drmModeObjectGetProperties(dev->fd, r->connectors[i],
- DRM_MODE_OBJECT_CONNECTOR);
- if (!props) {
- printf("failed to get connector properties\n");
- goto err;
- }
-
- dev->connectors[i].crtc_id_pid = get_prop_id(dev, props,
- "CRTC_ID");
- drmModeFreeObjectProperties(props);
- if (!dev->connectors[i].crtc_id_pid)
- goto err;
- }
-
- dev->num_encoders = r->count_encoders;
- dev->encoders = calloc(dev->num_encoders, sizeof(*dev->encoders));
- if (!dev->encoders) {
- printf("failed to allocate encoders\n");
- goto err;
- }
- for (i = 0; i < dev->num_encoders; i++) {
- dev->encoders[i] = drmModeGetEncoder(dev->fd, r->encoders[i]);
- if (!dev->encoders[i]) {
- printf("failed to get encoder %d\n", i);
- goto err;
- }
- }
-
- dev->num_crtcs = r->count_crtcs;
- dev->crtcs = calloc(dev->num_crtcs, sizeof(struct sp_crtc));
- if (!dev->crtcs) {
- printf("failed to allocate crtcs\n");
- goto err;
- }
- for (i = 0; i < dev->num_crtcs; i++) {
- drmModeObjectPropertiesPtr props;
-
- dev->crtcs[i].crtc = drmModeGetCrtc(dev->fd, r->crtcs[i]);
- if (!dev->crtcs[i].crtc) {
- printf("failed to get crtc %d\n", i);
- goto err;
- }
- dev->crtcs[i].pipe = i;
- dev->crtcs[i].num_planes = 0;
-
- props = drmModeObjectGetProperties(dev->fd, r->crtcs[i],
- DRM_MODE_OBJECT_CRTC);
- if (!props) {
- printf("failed to get crtc properties\n");
- goto err;
- }
-
- dev->crtcs[i].mode_pid = get_prop_id(dev, props, "MODE_ID");
- dev->crtcs[i].active_pid = get_prop_id(dev, props, "ACTIVE");
- drmModeFreeObjectProperties(props);
- if (!dev->crtcs[i].mode_pid || !dev->crtcs[i].active_pid)
- goto err;
- }
-
- pr = drmModeGetPlaneResources(dev->fd);
- if (!pr) {
- printf("failed to get plane resources\n");
- goto err;
- }
- dev->num_planes = pr->count_planes;
- dev->planes = calloc(dev->num_planes, sizeof(struct sp_plane));
- for(i = 0; i < dev->num_planes; i++) {
- drmModeObjectPropertiesPtr props;
- struct sp_plane *plane = &dev->planes[i];
-
- plane->dev = dev;
- plane->plane = drmModeGetPlane(dev->fd, pr->planes[i]);
- if (!plane->plane) {
- printf("failed to get plane %d\n", i);
- goto err;
- }
- plane->bo = NULL;
- plane->in_use = 0;
-
- ret = get_supported_format(plane, &plane->format);
- if (ret) {
- printf("failed to get supported format: %d\n", ret);
- goto err;
- }
-
- for (j = 0; j < dev->num_crtcs; j++) {
- if (plane->plane->possible_crtcs & (1 << j))
- dev->crtcs[j].num_planes++;
- }
-
- props = drmModeObjectGetProperties(dev->fd, pr->planes[i],
- DRM_MODE_OBJECT_PLANE);
- if (!props) {
- printf("failed to get plane properties\n");
- goto err;
- }
- plane->crtc_pid = get_prop_id(dev, props, "CRTC_ID");
- if (!plane->crtc_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->fb_pid = get_prop_id(dev, props, "FB_ID");
- if (!plane->fb_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->crtc_x_pid = get_prop_id(dev, props, "CRTC_X");
- if (!plane->crtc_x_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->crtc_y_pid = get_prop_id(dev, props, "CRTC_Y");
- if (!plane->crtc_y_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->crtc_w_pid = get_prop_id(dev, props, "CRTC_W");
- if (!plane->crtc_w_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->crtc_h_pid = get_prop_id(dev, props, "CRTC_H");
- if (!plane->crtc_h_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->src_x_pid = get_prop_id(dev, props, "SRC_X");
- if (!plane->src_x_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->src_y_pid = get_prop_id(dev, props, "SRC_Y");
- if (!plane->src_y_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->src_w_pid = get_prop_id(dev, props, "SRC_W");
- if (!plane->src_w_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- plane->src_h_pid = get_prop_id(dev, props, "SRC_H");
- if (!plane->src_h_pid) {
- drmModeFreeObjectProperties(props);
- goto err;
- }
- drmModeFreeObjectProperties(props);
- }
-
- if (pr)
- drmModeFreePlaneResources(pr);
- if (r)
- drmModeFreeResources(r);
-
- return dev;
-err:
- if (pr)
- drmModeFreePlaneResources(pr);
- if (r)
- drmModeFreeResources(r);
- destroy_sp_dev(dev);
- return NULL;
-}
-
-void destroy_sp_dev(struct sp_dev *dev)
-{
- int i;
-
- if (dev->planes) {
- for (i = 0; i< dev->num_planes; i++) {
- if (dev->planes[i].in_use)
- put_sp_plane(&dev->planes[i]);
- if (dev->planes[i].plane)
- drmModeFreePlane(dev->planes[i].plane);
- if (dev->planes[i].bo)
- free_sp_bo(dev->planes[i].bo);
- }
- free(dev->planes);
- }
- if (dev->crtcs) {
- for (i = 0; i< dev->num_crtcs; i++) {
- if (dev->crtcs[i].crtc)
- drmModeFreeCrtc(dev->crtcs[i].crtc);
- }
- free(dev->crtcs);
- }
- if (dev->encoders) {
- for (i = 0; i< dev->num_encoders; i++) {
- if (dev->encoders[i])
- drmModeFreeEncoder(dev->encoders[i]);
- }
- free(dev->encoders);
- }
- if (dev->connectors) {
- for (i = 0; i< dev->num_connectors; i++) {
- if (dev->connectors[i].conn)
- drmModeFreeConnector(dev->connectors[i].conn);
- }
- free(dev->connectors);
- }
-
- close(dev->fd);
- free(dev);
-}
diff --git a/tests/planetest/dev.h b/tests/planetest/dev.h
deleted file mode 100644
index 04dec794..00000000
--- a/tests/planetest/dev.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef __DEV_H_INCLUDED__
-#define __DEV_H_INCLUDED__
-
-#include <stdint.h>
-#include <xf86drmMode.h>
-
-struct sp_bo;
-struct sp_dev;
-
-struct sp_plane {
- struct sp_dev *dev;
- drmModePlanePtr plane;
- struct sp_bo *bo;
- int in_use;
- uint32_t format;
-
- /* Property ID's */
- uint32_t crtc_pid;
- uint32_t fb_pid;
- uint32_t zpos_pid;
- uint32_t crtc_x_pid;
- uint32_t crtc_y_pid;
- uint32_t crtc_w_pid;
- uint32_t crtc_h_pid;
- uint32_t src_x_pid;
- uint32_t src_y_pid;
- uint32_t src_w_pid;
- uint32_t src_h_pid;
-};
-
-struct sp_connector {
- drmModeConnectorPtr conn;
- uint32_t crtc_id_pid;
-};
-
-struct sp_crtc {
- drmModeCrtcPtr crtc;
- int pipe;
- int num_planes;
- uint32_t mode_pid;
- uint32_t active_pid;
-};
-
-struct sp_dev {
- int fd;
-
- int num_connectors;
- struct sp_connector *connectors;
-
- int num_encoders;
- drmModeEncoderPtr *encoders;
-
- int num_crtcs;
- struct sp_crtc *crtcs;
-
- int num_planes;
- struct sp_plane *planes;
-};
-
-void parse_arguments(int argc, char *argv[], int *card, int *crtc);
-
-struct sp_dev *create_sp_dev(int card);
-void destroy_sp_dev(struct sp_dev *dev);
-
-#endif /* __DEV_H_INCLUDED__ */
diff --git a/tests/planetest/modeset.c b/tests/planetest/modeset.c
deleted file mode 100644
index 037814ec..00000000
--- a/tests/planetest/modeset.c
+++ /dev/null
@@ -1,232 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <drm_fourcc.h>
-
-#include "modeset.h"
-#include "bo.h"
-#include "dev.h"
-
-static int set_crtc_mode(struct sp_dev *dev, struct sp_crtc *crtc,
- struct sp_connector *conn, drmModeModeInfoPtr mode)
-{
- int ret;
- struct drm_mode_create_blob create_blob;
- drmModePropertySetPtr pset;
-
- memset(&create_blob, 0, sizeof(create_blob));
- create_blob.length = sizeof(struct drm_mode_modeinfo);
- create_blob.data = (__u64)(uintptr_t)mode;
-
- ret = drmIoctl(dev->fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create_blob);
- if (ret) {
- printf("Failed to create mode property blob %d", ret);
- return ret;
- }
-
- pset = drmModePropertySetAlloc();
- if (!pset) {
- printf("Failed to allocate property set");
- return -1;
- }
-
- ret = drmModePropertySetAdd(pset, crtc->crtc->crtc_id,
- crtc->mode_pid, create_blob.blob_id) ||
- drmModePropertySetAdd(pset, crtc->crtc->crtc_id,
- crtc->active_pid, 1) ||
- drmModePropertySetAdd(pset, conn->conn->connector_id,
- conn->crtc_id_pid, crtc->crtc->crtc_id);
- if (ret) {
- printf("Failed to add blob %d to pset", create_blob.blob_id);
- drmModePropertySetFree(pset);
- return ret;
- }
-
- ret = drmModePropertySetCommit(dev->fd, DRM_MODE_ATOMIC_ALLOW_MODESET,
- NULL, pset);
-
- drmModePropertySetFree(pset);
-
- if (ret) {
- printf("Failed to commit pset ret=%d\n", ret);
- return ret;
- }
-
- memcpy(&crtc->crtc->mode, mode, sizeof(struct drm_mode_modeinfo));
- crtc->crtc->mode_valid = 1;
- return 0;
-}
-
-int initialize_screens(struct sp_dev *dev)
-{
- int ret, i, j;
- unsigned crtc_mask = 0;
-
- for (i = 0; i < dev->num_connectors; i++) {
- struct sp_connector *c = &dev->connectors[i];
- drmModeModeInfoPtr m = NULL;
- drmModeEncoderPtr e = NULL;
- struct sp_crtc *cr = NULL;
-
- if (c->conn->connection != DRM_MODE_CONNECTED)
- continue;
-
- if (!c->conn->count_modes) {
- printf("connector has no modes, skipping\n");
- continue;
- }
-
- /* Take the first unless there's a preferred mode */
- m = &c->conn->modes[0];
- for (j = 0; j < c->conn->count_modes; j++) {
- drmModeModeInfoPtr tmp_m = &c->conn->modes[j];
-
- if (!(tmp_m->type & DRM_MODE_TYPE_PREFERRED))
- continue;
-
- m = tmp_m;
- break;
- }
-
- if (!c->conn->count_encoders) {
- printf("no possible encoders for connector\n");
- continue;
- }
-
- for (j = 0; j < dev->num_encoders; j++) {
- e = dev->encoders[j];
- if (e->encoder_id == c->conn->encoders[0])
- break;
- }
- if (j == dev->num_encoders) {
- printf("could not find encoder for the connector\n");
- continue;
- }
-
- for (j = 0; j < dev->num_crtcs; j++) {
- if ((1 << j) & crtc_mask)
- continue;
-
- cr = &dev->crtcs[j];
-
- if ((1 << j) & e->possible_crtcs)
- break;
- }
- if (j == dev->num_crtcs) {
- printf("could not find crtc for the encoder\n");
- continue;
- }
-
- ret = set_crtc_mode(dev, cr, c, m);
- if (ret) {
- printf("failed to set mode!\n");
- continue;
- }
- crtc_mask |= 1 << j;
- }
- return 0;
-}
-
-struct sp_plane *get_sp_plane(struct sp_dev *dev, struct sp_crtc *crtc)
-{
- int i;
-
- for(i = 0; i < dev->num_planes; i++) {
- struct sp_plane *p = &dev->planes[i];
-
- if (p->in_use)
- continue;
-
- if (!(p->plane->possible_crtcs & (1 << crtc->pipe)))
- continue;
-
- p->in_use = 1;
- return p;
- }
- return NULL;
-}
-
-void put_sp_plane(struct sp_plane *plane)
-{
- drmModePlanePtr p;
-
- /* Get the latest plane information (most notably the crtc_id) */
- p = drmModeGetPlane(plane->dev->fd, plane->plane->plane_id);
- if (p)
- plane->plane = p;
-
- if (plane->bo) {
- free_sp_bo(plane->bo);
- plane->bo = NULL;
- }
- plane->in_use = 0;
-}
-
-int set_sp_plane(struct sp_dev *dev, struct sp_plane *plane,
- struct sp_crtc *crtc, int x, int y)
-{
- int ret;
- uint32_t w, h;
-
- w = plane->bo->width;
- h = plane->bo->height;
-
- if ((w + x) > crtc->crtc->mode.hdisplay)
- w = crtc->crtc->mode.hdisplay - x;
- if ((h + y) > crtc->crtc->mode.vdisplay)
- h = crtc->crtc->mode.vdisplay - y;
-
- ret = drmModeSetPlane(dev->fd, plane->plane->plane_id,
- crtc->crtc->crtc_id, plane->bo->fb_id, 0, x, y, w, h,
- 0, 0, w << 16, h << 16);
- if (ret) {
- printf("failed to set plane to crtc ret=%d\n", ret);
- return ret;
- }
-
- return ret;
-}
-int set_sp_plane_pset(struct sp_dev *dev, struct sp_plane *plane,
- drmModePropertySetPtr pset, struct sp_crtc *crtc, int x, int y)
-{
- int ret;
- uint32_t w, h;
-
- w = plane->bo->width;
- h = plane->bo->height;
-
- if ((w + x) > crtc->crtc->mode.hdisplay)
- w = crtc->crtc->mode.hdisplay - x;
- if ((h + y) > crtc->crtc->mode.vdisplay)
- h = crtc->crtc->mode.vdisplay - y;
-
- ret = drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->crtc_pid, crtc->crtc->crtc_id)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->fb_pid, plane->bo->fb_id)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->crtc_x_pid, x)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->crtc_y_pid, y)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->crtc_w_pid, w)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->crtc_h_pid, h)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->src_x_pid, 0)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->src_y_pid, 0)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->src_w_pid, w << 16)
- || drmModePropertySetAdd(pset, plane->plane->plane_id,
- plane->src_h_pid, h << 16);
- if (ret) {
- printf("failed to add properties to the set\n");
- return -1;
- }
-
- return ret;
-}
diff --git a/tests/planetest/modeset.h b/tests/planetest/modeset.h
deleted file mode 100644
index 7e965743..00000000
--- a/tests/planetest/modeset.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef __MODESET_H_INCLUDED__
-#define __MODESET_H_INCLUDED__
-
-struct sp_dev;
-struct sp_crtc;
-
-int initialize_screens(struct sp_dev *dev);
-
-
-struct sp_plane *get_sp_plane(struct sp_dev *dev, struct sp_crtc *crtc);
-void put_sp_plane(struct sp_plane *plane);
-
-int set_sp_plane(struct sp_dev *dev, struct sp_plane *plane,
- struct sp_crtc *crtc, int x, int y);
-
-int set_sp_plane_pset(struct sp_dev *dev, struct sp_plane *plane,
- drmModePropertySetPtr pset, struct sp_crtc *crtc, int x, int y);
-
-#endif /* __MODESET_H_INCLUDED__ */
diff --git a/tests/planetest/planetest.c b/tests/planetest/planetest.c
deleted file mode 100644
index 5e187c99..00000000
--- a/tests/planetest/planetest.c
+++ /dev/null
@@ -1,116 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <time.h>
-#include <errno.h>
-
-#include <xf86drm.h>
-
-#include "dev.h"
-#include "bo.h"
-#include "modeset.h"
-
-static int terminate = 0;
-
-static void sigint_handler(int arg)
-{
- terminate = 1;
-}
-
-static void incrementor(int *inc, int *val, int increment, int lower, int upper)
-{
- if(*inc > 0)
- *inc = *val + increment >= upper ? -1 : 1;
- else
- *inc = *val - increment <= lower ? 1 : -1;
- *val += *inc * increment;
-}
-
-int main(int argc, char *argv[])
-{
- int ret, i, j, num_test_planes;
- int x_inc = 1, x = 0, y_inc = 1, y = 0;
- uint32_t plane_w = 128, plane_h = 128;
- struct sp_dev *dev;
- struct sp_plane **plane = NULL;
- struct sp_crtc *test_crtc;
- int card = 0, crtc = 0;
-
- signal(SIGINT, sigint_handler);
-
- parse_arguments(argc, argv, &card, &crtc);
-
- dev = create_sp_dev(card);
- if (!dev) {
- printf("Failed to create sp_dev\n");
- return -1;
- }
-
- if (crtc >= dev->num_crtcs) {
- printf("Invalid crtc %d (num=%d)\n", crtc, dev->num_crtcs);
- return -1;
- }
-
- ret = initialize_screens(dev);
- if (ret) {
- printf("Failed to initialize screens\n");
- goto out;
- }
- test_crtc = &dev->crtcs[crtc];
-
- plane = calloc(dev->num_planes, sizeof(*plane));
- if (!plane) {
- printf("Failed to allocate plane array\n");
- goto out;
- }
-
- /* Create our planes */
- num_test_planes = test_crtc->num_planes;
- for (i = 0; i < num_test_planes; i++) {
- plane[i] = get_sp_plane(dev, test_crtc);
- if (!plane[i]) {
- printf("no unused planes available\n");
- goto out;
- }
-
- plane[i]->bo = create_sp_bo(dev, plane_w, plane_h, 16,
- plane[i]->format, 0);
- if (!plane[i]->bo) {
- printf("failed to create plane bo\n");
- goto out;
- }
-
- fill_bo(plane[i]->bo, 0xFF, 0xFF, 0xFF, 0xFF);
- }
-
- while (!terminate) {
- incrementor(&x_inc, &x, 5, 0,
- test_crtc->crtc->mode.hdisplay - plane_w);
- incrementor(&y_inc, &y, 5, 0, test_crtc->crtc->mode.vdisplay -
- plane_h * num_test_planes);
-
- for (j = 0; j < num_test_planes; j++) {
- ret = set_sp_plane(dev, plane[j], test_crtc,
- x, y + j * plane_h);
- if (ret) {
- printf("failed to set plane %d %d\n", j, ret);
- goto out;
- }
- }
- usleep(15 * 1000);
- }
-
- for (i = 0; i < num_test_planes; i++)
- put_sp_plane(plane[i]);
-
-out:
- destroy_sp_dev(dev);
- free(plane);
- return ret;
-}
diff --git a/tests/proptest/Makefile.am b/tests/proptest/Makefile.am
index 3fde46be..33b8705b 100644
--- a/tests/proptest/Makefile.am
+++ b/tests/proptest/Makefile.am
@@ -2,6 +2,7 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS)\
+ -fvisibility=hidden \
-I$(top_srcdir)/include/drm \
-I$(top_srcdir)/tests \
-I$(top_srcdir)
diff --git a/tests/proptest/meson.build b/tests/proptest/meson.build
new file mode 100644
index 00000000..9c87965a
--- /dev/null
+++ b/tests/proptest/meson.build
@@ -0,0 +1,28 @@
+# 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.
+
+proptest = executable(
+ 'proptest',
+ files('proptest.c'),
+ c_args : libdrm_c_args,
+ include_directories : [inc_root, inc_tests, inc_drm],
+ link_with : [libdrm, libutil],
+ install : with_install_tests,
+)
diff --git a/tests/radeon/Makefile.am b/tests/radeon/Makefile.am
index 9da76259..3d173e31 100644
--- a/tests/radeon/Makefile.am
+++ b/tests/radeon/Makefile.am
@@ -1,5 +1,6 @@
AM_CFLAGS = \
$(WARN_CFLAGS)\
+ -fvisibility=hidden \
-I $(top_srcdir)/include/drm \
-I $(top_srcdir)
diff --git a/tests/radeon/meson.build b/tests/radeon/meson.build
new file mode 100644
index 00000000..bb345b73
--- /dev/null
+++ b/tests/radeon/meson.build
@@ -0,0 +1,27 @@
+# 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.
+
+radeon_ttm = executable(
+ 'radeon_ttm',
+ files('rbo.c', 'radeon_ttm.c'),
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ c_args : libdrm_c_args,
+)
diff --git a/tests/tegra/Makefile.am b/tests/tegra/Makefile.am
index 8e625c8f..b462a30c 100644
--- a/tests/tegra/Makefile.am
+++ b/tests/tegra/Makefile.am
@@ -3,7 +3,9 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/tegra \
-I$(top_srcdir)
-AM_CFLAGS = $(WARN_CFLAGS)
+AM_CFLAGS = \
+ $(WARN_CFLAGS) \
+ -fvisibility=hidden
LDADD = \
../../tegra/libdrm_tegra.la \
diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build
new file mode 100644
index 00000000..4f8c54f4
--- /dev/null
+++ b/tests/tegra/meson.build
@@ -0,0 +1,27 @@
+# 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.
+
+openclose = executable(
+ 'openclose',
+ files('openclose.c'),
+ include_directories : [inc_root, inc_drm, include_directories('../../tegra')],
+ c_args : libdrm_c_args,
+ link_with : [libdrm, libdrm_tegra],
+)
diff --git a/tests/tegra/openclose.c b/tests/tegra/openclose.c
index 881d8aa4..f80f52d4 100644
--- a/tests/tegra/openclose.c
+++ b/tests/tegra/openclose.c
@@ -20,10 +20,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
diff --git a/tests/util/format.c b/tests/util/format.c
index 043cfe7f..15ac5e1e 100644
--- a/tests/util/format.c
+++ b/tests/util/format.c
@@ -23,10 +23,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
diff --git a/tests/util/kms.c b/tests/util/kms.c
index 959b6881..5af8bf20 100644
--- a/tests/util/kms.c
+++ b/tests/util/kms.c
@@ -37,10 +37,6 @@
* the mode has been programmed, along with possible test patterns.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
@@ -79,6 +75,7 @@ static const struct type_name encoder_type_names[] = {
{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
{ DRM_MODE_ENCODER_DSI, "DSI" },
{ DRM_MODE_ENCODER_DPMST, "DPMST" },
+ { DRM_MODE_ENCODER_DPI, "DPI" },
};
const char *util_lookup_encoder_type_name(unsigned int type)
@@ -117,6 +114,7 @@ static const struct type_name connector_type_names[] = {
{ 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)
@@ -145,6 +143,9 @@ static const char * const modules[] = {
"virtio_gpu",
"mediatek",
"meson",
+ "pl111",
+ "stm",
+ "sun4i-drm",
};
int util_open(const char *device, const char *module)
diff --git a/tests/util/meson.build b/tests/util/meson.build
new file mode 100644
index 00000000..7fa1a4b7
--- /dev/null
+++ b/tests/util/meson.build
@@ -0,0 +1,28 @@
+# 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.
+
+
+libutil = static_library(
+ 'util',
+ [files('format.c', 'kms.c', 'pattern.c'), config_file],
+ include_directories : [inc_root, inc_drm],
+ link_with : libdrm,
+ dependencies : dep_cairo
+)
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index 00b08a8c..9fa0a417 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -23,10 +23,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -34,7 +30,7 @@
#include <drm_fourcc.h>
-#ifdef HAVE_CAIRO
+#if HAVE_CAIRO
#include <cairo.h>
#include <math.h>
#endif
@@ -546,10 +542,9 @@ static void fill_smpte(const struct util_format_info *info, void *planes[3],
static void make_pwetty(void *data, unsigned int width, unsigned int height,
unsigned int stride, uint32_t format)
{
-#ifdef HAVE_CAIRO
+#if HAVE_CAIRO
cairo_surface_t *surface;
cairo_t *cr;
- int x, y;
cairo_format_t cairo_format;
/* we can ignore the order of R,G,B channels */
@@ -576,8 +571,8 @@ static void make_pwetty(void *data, unsigned int width, unsigned int height,
cairo_surface_destroy(surface);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
- for (x = 0; x < width; x += 250)
- for (y = 0; y < height; y += 250) {
+ for (unsigned x = 0; x < width; x += 250)
+ for (unsigned y = 0; y < height; y += 250) {
char buf[64];
cairo_move_to(cr, x, y - 20);
@@ -824,8 +819,8 @@ static void fill_tiles(const struct util_format_info *info, void *planes[3],
}
}
-static void fill_plain(const struct util_format_info *info, void *planes[3],
- unsigned int width, unsigned int height,
+static void fill_plain(void *planes[3],
+ unsigned int height,
unsigned int stride)
{
memset(planes[0], 0x77, stride * height);
@@ -861,7 +856,7 @@ void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
return fill_smpte(info, planes, width, height, stride);
case UTIL_PATTERN_PLAIN:
- return fill_plain(info, planes, width, height, stride);
+ return fill_plain(planes, height, stride);
default:
printf("Error: unsupported test pattern %u.\n", pattern);
diff --git a/tests/vbltest/Makefile.am b/tests/vbltest/Makefile.am
index 276afad5..b6cd7a4d 100644
--- a/tests/vbltest/Makefile.am
+++ b/tests/vbltest/Makefile.am
@@ -1,5 +1,6 @@
AM_CFLAGS = \
$(WARN_CFLAGS)\
+ -fvisibility=hidden \
-I$(top_srcdir)/include/drm \
-I$(top_srcdir)/tests \
-I$(top_srcdir)
diff --git a/tests/vbltest/meson.build b/tests/vbltest/meson.build
new file mode 100644
index 00000000..6339feba
--- /dev/null
+++ b/tests/vbltest/meson.build
@@ -0,0 +1,28 @@
+# 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.
+
+vbltest = executable(
+ 'vbltest',
+ files('vbltest.c'),
+ c_args : libdrm_c_args,
+ include_directories : [inc_root, inc_tests, inc_drm],
+ link_with : [libdrm, libutil],
+ install : with_install_tests,
+)
diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c
index 3f6b803a..48708d20 100644
--- a/tests/vbltest/vbltest.c
+++ b/tests/vbltest/vbltest.c
@@ -24,10 +24,6 @@
* IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/util_math.h b/util_math.h
index 02b15a8e..35bf4512 100644
--- a/util_math.h
+++ b/util_math.h
@@ -29,6 +29,6 @@
#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C))
#define __align_mask(value, mask) (((value) + (mask)) & ~(mask))
-#define ALIGN(value, alignment) __align_mask(value, (typeof(value))((alignment) - 1))
+#define ALIGN(value, alignment) __align_mask(value, (__typeof__(value))((alignment) - 1))
#endif /*_UTIL_MATH_H_*/
diff --git a/vc4/Makefile.am b/vc4/Makefile.am
index 7e486b4d..5f82d04e 100644
--- a/vc4/Makefile.am
+++ b/vc4/Makefile.am
@@ -23,6 +23,7 @@ include Makefile.sources
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -fvisibility=hidden \
-I$(top_srcdir) \
$(PTHREADSTUBS_CFLAGS) \
$(VALGRIND_CFLAGS) \
diff --git a/vc4/meson.build b/vc4/meson.build
new file mode 100644
index 00000000..0136987b
--- /dev/null
+++ b/vc4/meson.build
@@ -0,0 +1,28 @@
+# 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.
+
+install_headers('vc4_packet.h', 'vc4_qpu_defines.h', subdir : 'libdrm')
+
+pkg.generate(
+ name : 'libdrm_vc4',
+ version : meson.project_version(),
+ requires_private : 'libdrm',
+ description : 'Userspace interface to vc4 kernel DRM services',
+)
diff --git a/xf86atomic.h b/xf86atomic.h
index 922b37da..2d733bd5 100644
--- a/xf86atomic.h
+++ b/xf86atomic.h
@@ -34,10 +34,6 @@
#ifndef LIBDRM_ATOMICS_H
#define LIBDRM_ATOMICS_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#if HAVE_LIBDRM_ATOMIC_PRIMITIVES
#define HAS_ATOMIC_OPS 1
@@ -101,7 +97,7 @@ typedef struct { LIBDRM_ATOMIC_TYPE atomic; } atomic_t;
#endif
-#if ! HAS_ATOMIC_OPS
+#if !defined(HAS_ATOMIC_OPS)
#error libdrm requires atomic operations, please define them for your CPU/compiler.
#endif
diff --git a/xf86drm.c b/xf86drm.c
index 82fb0e22..a5b0bb74 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -31,9 +31,6 @@
* DEALINGS IN THE SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -62,6 +59,8 @@
#endif
#include <math.h>
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
/* Not all systems have MAP_FAILED defined */
#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1)
@@ -102,7 +101,7 @@
#define DRM_MAJOR 226 /* Linux */
#endif
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) || defined(__DragonFly__)
struct drm_pciinfo {
uint16_t domain;
uint8_t bus;
@@ -124,7 +123,7 @@ struct drm_pciinfo {
static drmServerInfoPtr drm_server_info;
-void drmSetServerInfo(drmServerInfoPtr info)
+drm_public void drmSetServerInfo(drmServerInfoPtr info)
{
drm_server_info = info;
}
@@ -144,7 +143,7 @@ drmDebugPrint(const char *format, va_list ap)
return vfprintf(stderr, format, ap);
}
-void
+drm_public void
drmMsg(const char *format, ...)
{
va_list ap;
@@ -164,17 +163,17 @@ drmMsg(const char *format, ...)
static void *drmHashTable = NULL; /* Context switch callbacks */
-void *drmGetHashTable(void)
+drm_public void *drmGetHashTable(void)
{
return drmHashTable;
}
-void *drmMalloc(int size)
+drm_public void *drmMalloc(int size)
{
return calloc(1, size);
}
-void drmFree(void *pt)
+drm_public void drmFree(void *pt)
{
free(pt);
}
@@ -182,7 +181,7 @@ void drmFree(void *pt)
/**
* Call ioctl, restarting if it is interupted
*/
-int
+drm_public int
drmIoctl(int fd, unsigned long request, void *arg)
{
int ret;
@@ -202,7 +201,7 @@ static unsigned long drmGetKeyFromFd(int fd)
return st.st_rdev;
}
-drmHashEntry *drmGetEntry(int fd)
+drm_public drmHashEntry *drmGetEntry(int fd)
{
unsigned long key = drmGetKeyFromFd(fd);
void *value;
@@ -293,7 +292,7 @@ static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
* If any other failure happened then it will output error mesage using
* drmMsg() call.
*/
-#if !defined(UDEV)
+#if !UDEV
static int chown_check_return(const char *path, uid_t owner, gid_t group)
{
int rv;
@@ -332,7 +331,7 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
int fd;
mode_t devmode = DRM_DEV_MODE, serv_mode;
gid_t serv_group;
-#if !defined(UDEV)
+#if !UDEV
int isroot = !geteuid();
uid_t user = DRM_DEV_UID;
gid_t group = DRM_DEV_GID;
@@ -361,7 +360,7 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
}
-#if !defined(UDEV)
+#if !UDEV
if (stat(DRM_DIR_NAME, &st)) {
if (!isroot)
return DRM_ERR_NOT_ROOT;
@@ -408,13 +407,13 @@ wait_for_udev:
}
#endif
- fd = open(buf, O_RDWR, 0);
+ fd = open(buf, O_RDWR | O_CLOEXEC, 0);
drmMsg("drmOpenDevice: open result is %d, (%s)\n",
fd, fd < 0 ? strerror(errno) : "OK");
if (fd >= 0)
return fd;
-#if !defined(UDEV)
+#if !UDEV
/* Check if the device node is not what we expect it to be, and recreate it
* and try again if so.
*/
@@ -428,7 +427,7 @@ wait_for_udev:
chmod(buf, devmode);
}
}
- fd = open(buf, O_RDWR, 0);
+ fd = open(buf, O_RDWR | O_CLOEXEC, 0);
drmMsg("drmOpenDevice: open result is %d, (%s)\n",
fd, fd < 0 ? strerror(errno) : "OK");
if (fd >= 0)
@@ -477,7 +476,7 @@ static int drmOpenMinor(int minor, int create, int type)
};
sprintf(buf, dev_name, DRM_DIR_NAME, minor);
- if ((fd = open(buf, O_RDWR, 0)) >= 0)
+ if ((fd = open(buf, O_RDWR | O_CLOEXEC, 0)) >= 0)
return fd;
return -errno;
}
@@ -493,7 +492,7 @@ static int drmOpenMinor(int minor, int create, int type)
* minor and get version information. For backward compatibility with older
* Linux implementations, /proc/dri is also checked.
*/
-int drmAvailable(void)
+drm_public int drmAvailable(void)
{
drmVersionPtr version;
int retval = 0;
@@ -728,7 +727,7 @@ static int drmOpenByName(const char *name, int type)
* It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
* otherwise.
*/
-int drmOpen(const char *name, const char *busid)
+drm_public int drmOpen(const char *name, const char *busid)
{
return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
}
@@ -749,7 +748,7 @@ int drmOpen(const char *name, const char *busid)
* It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
* otherwise.
*/
-int drmOpenWithType(const char *name, const char *busid, int type)
+drm_public int drmOpenWithType(const char *name, const char *busid, int type)
{
if (name != NULL && drm_server_info &&
drm_server_info->load_module && !drmAvailable()) {
@@ -772,12 +771,12 @@ int drmOpenWithType(const char *name, const char *busid, int type)
return -1;
}
-int drmOpenControl(int minor)
+drm_public int drmOpenControl(int minor)
{
return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
}
-int drmOpenRender(int minor)
+drm_public int drmOpenRender(int minor)
{
return drmOpenMinor(minor, 0, DRM_NODE_RENDER);
}
@@ -791,7 +790,7 @@ int drmOpenRender(int minor)
* It frees the memory pointed by \p %v as well as all the non-null strings
* pointers in it.
*/
-void drmFreeVersion(drmVersionPtr v)
+drm_public void drmFreeVersion(drmVersionPtr v)
{
if (!v)
return;
@@ -861,13 +860,11 @@ static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
* first with zeros to get the string lengths, and then the actually strings.
* It also null-terminates them since they might not be already.
*/
-drmVersionPtr drmGetVersion(int fd)
+drm_public drmVersionPtr drmGetVersion(int fd)
{
drmVersionPtr retval;
drm_version_t *version = drmMalloc(sizeof(*version));
- memclear(*version);
-
if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
drmFreeKernelVersion(version);
return NULL;
@@ -911,7 +908,7 @@ drmVersionPtr drmGetVersion(int fd)
* This function allocates and fills a drm_version structure with a hard coded
* version number.
*/
-drmVersionPtr drmGetLibVersion(int fd)
+drm_public drmVersionPtr drmGetLibVersion(int fd)
{
drm_version_t *version = drmMalloc(sizeof(*version));
@@ -932,7 +929,7 @@ drmVersionPtr drmGetLibVersion(int fd)
return (drmVersionPtr)version;
}
-int drmGetCap(int fd, uint64_t capability, uint64_t *value)
+drm_public int drmGetCap(int fd, uint64_t capability, uint64_t *value)
{
struct drm_get_cap cap;
int ret;
@@ -948,7 +945,7 @@ int drmGetCap(int fd, uint64_t capability, uint64_t *value)
return 0;
}
-int drmSetClientCap(int fd, uint64_t capability, uint64_t value)
+drm_public int drmSetClientCap(int fd, uint64_t capability, uint64_t value)
{
struct drm_set_client_cap cap;
@@ -967,7 +964,7 @@ int drmSetClientCap(int fd, uint64_t capability, uint64_t value)
* \internal
* This function is just frees the memory pointed by \p busid.
*/
-void drmFreeBusid(const char *busid)
+drm_public void drmFreeBusid(const char *busid)
{
drmFree((void *)busid);
}
@@ -985,7 +982,7 @@ void drmFreeBusid(const char *busid)
* get the string length and data, passing the arguments in a drm_unique
* structure.
*/
-char *drmGetBusid(int fd)
+drm_public char *drmGetBusid(int fd)
{
drm_unique_t u;
@@ -994,8 +991,10 @@ char *drmGetBusid(int fd)
if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
return NULL;
u.unique = drmMalloc(u.unique_len + 1);
- if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
+ if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) {
+ drmFree(u.unique);
return NULL;
+ }
u.unique[u.unique_len] = '\0';
return u.unique;
@@ -1014,7 +1013,7 @@ char *drmGetBusid(int fd)
* This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
* the arguments in a drm_unique structure.
*/
-int drmSetBusid(int fd, const char *busid)
+drm_public int drmSetBusid(int fd, const char *busid)
{
drm_unique_t u;
@@ -1028,7 +1027,7 @@ int drmSetBusid(int fd, const char *busid)
return 0;
}
-int drmGetMagic(int fd, drm_magic_t * magic)
+drm_public int drmGetMagic(int fd, drm_magic_t * magic)
{
drm_auth_t auth;
@@ -1041,7 +1040,7 @@ int drmGetMagic(int fd, drm_magic_t * magic)
return 0;
}
-int drmAuthMagic(int fd, drm_magic_t magic)
+drm_public int drmAuthMagic(int fd, drm_magic_t magic)
{
drm_auth_t auth;
@@ -1102,8 +1101,8 @@ int drmAuthMagic(int fd, drm_magic_t magic)
* This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
* the arguments in a drm_map structure.
*/
-int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
- drmMapFlags flags, drm_handle_t *handle)
+drm_public int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
+ drmMapFlags flags, drm_handle_t *handle)
{
drm_map_t map;
@@ -1119,7 +1118,7 @@ int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
return 0;
}
-int drmRmMap(int fd, drm_handle_t handle)
+drm_public int drmRmMap(int fd, drm_handle_t handle)
{
drm_map_t map;
@@ -1147,8 +1146,8 @@ int drmRmMap(int fd, drm_handle_t handle)
*
* \sa drm_buf_desc.
*/
-int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
- int agp_offset)
+drm_public int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
+ int agp_offset)
{
drm_buf_desc_t request;
@@ -1163,7 +1162,7 @@ int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
return request.count;
}
-int drmMarkBufs(int fd, double low, double high)
+drm_public int drmMarkBufs(int fd, double low, double high)
{
drm_buf_info_t info;
int i;
@@ -1214,7 +1213,7 @@ int drmMarkBufs(int fd, double low, double high)
* This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
* the arguments in a drm_buf_free structure.
*/
-int drmFreeBufs(int fd, int count, int *list)
+drm_public int drmFreeBufs(int fd, int count, int *list)
{
drm_buf_free_t request;
@@ -1235,7 +1234,7 @@ int drmFreeBufs(int fd, int count, int *list)
* \internal
* This function closes the file descriptor.
*/
-int drmClose(int fd)
+drm_public int drmClose(int fd)
{
unsigned long key = drmGetKeyFromFd(fd);
drmHashEntry *entry = drmGetEntry(fd);
@@ -1266,7 +1265,8 @@ int drmClose(int fd)
* \internal
* This function is a wrapper for mmap().
*/
-int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
+drm_public int drmMap(int fd, drm_handle_t handle, drmSize size,
+ drmAddressPtr address)
{
static unsigned long pagesize_mask = 0;
@@ -1296,12 +1296,12 @@ int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
* \internal
* This function is a wrapper for munmap().
*/
-int drmUnmap(drmAddress address, drmSize size)
+drm_public int drmUnmap(drmAddress address, drmSize size)
{
return drm_munmap(address, size);
}
-drmBufInfoPtr drmGetBufInfo(int fd)
+drm_public drmBufInfoPtr drmGetBufInfo(int fd)
{
drm_buf_info_t info;
drmBufInfoPtr retval;
@@ -1351,7 +1351,7 @@ drmBufInfoPtr drmGetBufInfo(int fd)
* information about the buffers in a drm_buf_map structure into the
* client-visible data structures.
*/
-drmBufMapPtr drmMapBufs(int fd)
+drm_public drmBufMapPtr drmMapBufs(int fd)
{
drm_buf_map_t bufs;
drmBufMapPtr retval;
@@ -1396,7 +1396,7 @@ drmBufMapPtr drmMapBufs(int fd)
* Calls munmap() for every buffer stored in \p bufs and frees the
* memory allocated by drmMapBufs().
*/
-int drmUnmapBufs(drmBufMapPtr bufs)
+drm_public int drmUnmapBufs(drmBufMapPtr bufs)
{
int i;
@@ -1424,7 +1424,7 @@ int drmUnmapBufs(drmBufMapPtr bufs)
* Assemble the arguments into a drm_dma structure and keeps issuing the
* DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
*/
-int drmDMA(int fd, drmDMAReqPtr request)
+drm_public int drmDMA(int fd, drmDMAReqPtr request)
{
drm_dma_t dma;
int ret, i = 0;
@@ -1467,7 +1467,7 @@ int drmDMA(int fd, drmDMAReqPtr request)
* This function translates the arguments into a drm_lock structure and issue
* the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
*/
-int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
+drm_public int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
{
drm_lock_t lock;
@@ -1498,7 +1498,7 @@ int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
* This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
* argument in a drm_lock structure.
*/
-int drmUnlock(int fd, drm_context_t context)
+drm_public int drmUnlock(int fd, drm_context_t context)
{
drm_lock_t lock;
@@ -1507,7 +1507,7 @@ int drmUnlock(int fd, drm_context_t context)
return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
}
-drm_context_t *drmGetReservedContextList(int fd, int *count)
+drm_public drm_context_t *drmGetReservedContextList(int fd, int *count)
{
drm_ctx_res_t res;
drm_ctx_t *list;
@@ -1523,14 +1523,12 @@ drm_context_t *drmGetReservedContextList(int fd, int *count)
if (!(list = drmMalloc(res.count * sizeof(*list))))
return NULL;
- if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
- drmFree(list);
- return NULL;
- }
+ if (!(retval = drmMalloc(res.count * sizeof(*retval))))
+ goto err_free_list;
res.contexts = list;
if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
- return NULL;
+ goto err_free_context;
for (i = 0; i < res.count; i++)
retval[i] = list[i].handle;
@@ -1538,9 +1536,15 @@ drm_context_t *drmGetReservedContextList(int fd, int *count)
*count = res.count;
return retval;
+
+err_free_list:
+ drmFree(list);
+err_free_context:
+ drmFree(retval);
+ return NULL;
}
-void drmFreeReservedContextList(drm_context_t *pt)
+drm_public void drmFreeReservedContextList(drm_context_t *pt)
{
drmFree(pt);
}
@@ -1563,7 +1567,7 @@ void drmFreeReservedContextList(drm_context_t *pt)
* This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
* argument in a drm_ctx structure.
*/
-int drmCreateContext(int fd, drm_context_t *handle)
+drm_public int drmCreateContext(int fd, drm_context_t *handle)
{
drm_ctx_t ctx;
@@ -1574,7 +1578,7 @@ int drmCreateContext(int fd, drm_context_t *handle)
return 0;
}
-int drmSwitchToContext(int fd, drm_context_t context)
+drm_public int drmSwitchToContext(int fd, drm_context_t context)
{
drm_ctx_t ctx;
@@ -1585,7 +1589,8 @@ int drmSwitchToContext(int fd, drm_context_t context)
return 0;
}
-int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
+drm_public int drmSetContextFlags(int fd, drm_context_t context,
+ drm_context_tFlags flags)
{
drm_ctx_t ctx;
@@ -1606,8 +1611,8 @@ int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
return 0;
}
-int drmGetContextFlags(int fd, drm_context_t context,
- drm_context_tFlagsPtr flags)
+drm_public int drmGetContextFlags(int fd, drm_context_t context,
+ drm_context_tFlagsPtr flags)
{
drm_ctx_t ctx;
@@ -1640,7 +1645,7 @@ int drmGetContextFlags(int fd, drm_context_t context,
* This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
* argument in a drm_ctx structure.
*/
-int drmDestroyContext(int fd, drm_context_t handle)
+drm_public int drmDestroyContext(int fd, drm_context_t handle)
{
drm_ctx_t ctx;
@@ -1651,7 +1656,7 @@ int drmDestroyContext(int fd, drm_context_t handle)
return 0;
}
-int drmCreateDrawable(int fd, drm_drawable_t *handle)
+drm_public int drmCreateDrawable(int fd, drm_drawable_t *handle)
{
drm_draw_t draw;
@@ -1662,7 +1667,7 @@ int drmCreateDrawable(int fd, drm_drawable_t *handle)
return 0;
}
-int drmDestroyDrawable(int fd, drm_drawable_t handle)
+drm_public int drmDestroyDrawable(int fd, drm_drawable_t handle)
{
drm_draw_t draw;
@@ -1673,9 +1678,9 @@ int drmDestroyDrawable(int fd, drm_drawable_t handle)
return 0;
}
-int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
- drm_drawable_info_type_t type, unsigned int num,
- void *data)
+drm_public int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
+ drm_drawable_info_type_t type,
+ unsigned int num, void *data)
{
drm_update_draw_t update;
@@ -1691,6 +1696,46 @@ int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
return 0;
}
+drm_public int drmCrtcGetSequence(int fd, uint32_t crtcId, uint64_t *sequence,
+ uint64_t *ns)
+{
+ struct drm_crtc_get_sequence get_seq;
+ int ret;
+
+ memclear(get_seq);
+ get_seq.crtc_id = crtcId;
+ ret = drmIoctl(fd, DRM_IOCTL_CRTC_GET_SEQUENCE, &get_seq);
+ if (ret)
+ return ret;
+
+ if (sequence)
+ *sequence = get_seq.sequence;
+ if (ns)
+ *ns = get_seq.sequence_ns;
+ return 0;
+}
+
+drm_public int drmCrtcQueueSequence(int fd, uint32_t crtcId, uint32_t flags,
+ uint64_t sequence,
+ uint64_t *sequence_queued,
+ uint64_t user_data)
+{
+ struct drm_crtc_queue_sequence queue_seq;
+ int ret;
+
+ memclear(queue_seq);
+ queue_seq.crtc_id = crtcId;
+ queue_seq.flags = flags;
+ queue_seq.sequence = sequence;
+ queue_seq.user_data = user_data;
+
+ ret = drmIoctl(fd, DRM_IOCTL_CRTC_QUEUE_SEQUENCE, &queue_seq);
+ if (ret == 0 && sequence_queued)
+ *sequence_queued = queue_seq.sequence;
+
+ return ret;
+}
+
/**
* Acquire the AGP device.
*
@@ -1703,7 +1748,7 @@ int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
* \internal
* This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
*/
-int drmAgpAcquire(int fd)
+drm_public int drmAgpAcquire(int fd)
{
if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
return -errno;
@@ -1721,7 +1766,7 @@ int drmAgpAcquire(int fd)
* \internal
* This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
*/
-int drmAgpRelease(int fd)
+drm_public int drmAgpRelease(int fd)
{
if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
return -errno;
@@ -1741,7 +1786,7 @@ int drmAgpRelease(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
* argument in a drm_agp_mode structure.
*/
-int drmAgpEnable(int fd, unsigned long mode)
+drm_public int drmAgpEnable(int fd, unsigned long mode)
{
drm_agp_mode_t m;
@@ -1769,8 +1814,8 @@ int drmAgpEnable(int fd, unsigned long mode)
* This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
* arguments in a drm_agp_buffer structure.
*/
-int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
- unsigned long *address, drm_handle_t *handle)
+drm_public int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
+ unsigned long *address, drm_handle_t *handle)
{
drm_agp_buffer_t b;
@@ -1799,7 +1844,7 @@ int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
* This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
* argument in a drm_agp_buffer structure.
*/
-int drmAgpFree(int fd, drm_handle_t handle)
+drm_public int drmAgpFree(int fd, drm_handle_t handle)
{
drm_agp_buffer_t b;
@@ -1824,7 +1869,7 @@ int drmAgpFree(int fd, drm_handle_t handle)
* This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
* argument in a drm_agp_binding structure.
*/
-int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
+drm_public int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
{
drm_agp_binding_t b;
@@ -1849,7 +1894,7 @@ int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
* This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
* the argument in a drm_agp_binding structure.
*/
-int drmAgpUnbind(int fd, drm_handle_t handle)
+drm_public int drmAgpUnbind(int fd, drm_handle_t handle)
{
drm_agp_binding_t b;
@@ -1872,7 +1917,7 @@ int drmAgpUnbind(int fd, drm_handle_t handle)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-int drmAgpVersionMajor(int fd)
+drm_public int drmAgpVersionMajor(int fd)
{
drm_agp_info_t i;
@@ -1895,7 +1940,7 @@ int drmAgpVersionMajor(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-int drmAgpVersionMinor(int fd)
+drm_public int drmAgpVersionMinor(int fd)
{
drm_agp_info_t i;
@@ -1918,7 +1963,7 @@ int drmAgpVersionMinor(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-unsigned long drmAgpGetMode(int fd)
+drm_public unsigned long drmAgpGetMode(int fd)
{
drm_agp_info_t i;
@@ -1941,7 +1986,7 @@ unsigned long drmAgpGetMode(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-unsigned long drmAgpBase(int fd)
+drm_public unsigned long drmAgpBase(int fd)
{
drm_agp_info_t i;
@@ -1964,7 +2009,7 @@ unsigned long drmAgpBase(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-unsigned long drmAgpSize(int fd)
+drm_public unsigned long drmAgpSize(int fd)
{
drm_agp_info_t i;
@@ -1987,7 +2032,7 @@ unsigned long drmAgpSize(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-unsigned long drmAgpMemoryUsed(int fd)
+drm_public unsigned long drmAgpMemoryUsed(int fd)
{
drm_agp_info_t i;
@@ -2010,7 +2055,7 @@ unsigned long drmAgpMemoryUsed(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-unsigned long drmAgpMemoryAvail(int fd)
+drm_public unsigned long drmAgpMemoryAvail(int fd)
{
drm_agp_info_t i;
@@ -2033,7 +2078,7 @@ unsigned long drmAgpMemoryAvail(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-unsigned int drmAgpVendorId(int fd)
+drm_public unsigned int drmAgpVendorId(int fd)
{
drm_agp_info_t i;
@@ -2056,7 +2101,7 @@ unsigned int drmAgpVendorId(int fd)
* This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
* necessary information in a drm_agp_info structure.
*/
-unsigned int drmAgpDeviceId(int fd)
+drm_public unsigned int drmAgpDeviceId(int fd)
{
drm_agp_info_t i;
@@ -2067,7 +2112,8 @@ unsigned int drmAgpDeviceId(int fd)
return i.id_device;
}
-int drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
+drm_public int drmScatterGatherAlloc(int fd, unsigned long size,
+ drm_handle_t *handle)
{
drm_scatter_gather_t sg;
@@ -2081,7 +2127,7 @@ int drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
return 0;
}
-int drmScatterGatherFree(int fd, drm_handle_t handle)
+drm_public int drmScatterGatherFree(int fd, drm_handle_t handle)
{
drm_scatter_gather_t sg;
@@ -2103,7 +2149,7 @@ int drmScatterGatherFree(int fd, drm_handle_t handle)
* \internal
* This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
*/
-int drmWaitVBlank(int fd, drmVBlankPtr vbl)
+drm_public int drmWaitVBlank(int fd, drmVBlankPtr vbl)
{
struct timespec timeout, cur;
int ret;
@@ -2135,7 +2181,7 @@ out:
return ret;
}
-int drmError(int err, const char *label)
+drm_public int drmError(int err, const char *label)
{
switch (err) {
case DRM_ERR_NO_DEVICE:
@@ -2172,7 +2218,7 @@ int drmError(int err, const char *label)
* This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
* argument in a drm_control structure.
*/
-int drmCtlInstHandler(int fd, int irq)
+drm_public int drmCtlInstHandler(int fd, int irq)
{
drm_control_t ctl;
@@ -2196,7 +2242,7 @@ int drmCtlInstHandler(int fd, int irq)
* This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
* argument in a drm_control structure.
*/
-int drmCtlUninstHandler(int fd)
+drm_public int drmCtlUninstHandler(int fd)
{
drm_control_t ctl;
@@ -2208,7 +2254,7 @@ int drmCtlUninstHandler(int fd)
return 0;
}
-int drmFinish(int fd, int context, drmLockFlags flags)
+drm_public int drmFinish(int fd, int context, drmLockFlags flags)
{
drm_lock_t lock;
@@ -2239,7 +2285,8 @@ int drmFinish(int fd, int context, drmLockFlags flags)
* This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
* arguments in a drm_irq_busid structure.
*/
-int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
+drm_public int drmGetInterruptFromBusID(int fd, int busnum, int devnum,
+ int funcnum)
{
drm_irq_busid_t p;
@@ -2252,7 +2299,7 @@ int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
return p.irq;
}
-int drmAddContextTag(int fd, drm_context_t context, void *tag)
+drm_public int drmAddContextTag(int fd, drm_context_t context, void *tag)
{
drmHashEntry *entry = drmGetEntry(fd);
@@ -2263,14 +2310,14 @@ int drmAddContextTag(int fd, drm_context_t context, void *tag)
return 0;
}
-int drmDelContextTag(int fd, drm_context_t context)
+drm_public int drmDelContextTag(int fd, drm_context_t context)
{
drmHashEntry *entry = drmGetEntry(fd);
return drmHashDelete(entry->tagTable, context);
}
-void *drmGetContextTag(int fd, drm_context_t context)
+drm_public void *drmGetContextTag(int fd, drm_context_t context)
{
drmHashEntry *entry = drmGetEntry(fd);
void *value;
@@ -2281,8 +2328,8 @@ void *drmGetContextTag(int fd, drm_context_t context)
return value;
}
-int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
- drm_handle_t handle)
+drm_public int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
+ drm_handle_t handle)
{
drm_ctx_priv_map_t map;
@@ -2295,8 +2342,8 @@ int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
return 0;
}
-int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
- drm_handle_t *handle)
+drm_public int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
+ drm_handle_t *handle)
{
drm_ctx_priv_map_t map;
@@ -2311,9 +2358,9 @@ int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
return 0;
}
-int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
- drmMapType *type, drmMapFlags *flags, drm_handle_t *handle,
- int *mtrr)
+drm_public int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
+ drmMapType *type, drmMapFlags *flags,
+ drm_handle_t *handle, int *mtrr)
{
drm_map_t map;
@@ -2330,8 +2377,8 @@ int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
return 0;
}
-int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
- unsigned long *magic, unsigned long *iocs)
+drm_public int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
+ unsigned long *magic, unsigned long *iocs)
{
drm_client_t client;
@@ -2347,7 +2394,7 @@ int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
return 0;
}
-int drmGetStats(int fd, drmStatsT *stats)
+drm_public int drmGetStats(int fd, drmStatsT *stats)
{
drm_stats_t s;
unsigned i;
@@ -2485,7 +2532,7 @@ int drmGetStats(int fd, drmStatsT *stats)
* It issues a read-write ioctl given by
* \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
*/
-int drmSetInterfaceVersion(int fd, drmSetVersion *version)
+drm_public int drmSetInterfaceVersion(int fd, drmSetVersion *version)
{
int retcode = 0;
drm_set_version_t sv;
@@ -2520,7 +2567,7 @@ int drmSetInterfaceVersion(int fd, drmSetVersion *version)
* It issues a ioctl given by
* \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
*/
-int drmCommandNone(int fd, unsigned long drmCommandIndex)
+drm_public int drmCommandNone(int fd, unsigned long drmCommandIndex)
{
unsigned long request;
@@ -2547,8 +2594,8 @@ int drmCommandNone(int fd, unsigned long drmCommandIndex)
* It issues a read ioctl given by
* \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
*/
-int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
- unsigned long size)
+drm_public int drmCommandRead(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size)
{
unsigned long request;
@@ -2576,8 +2623,8 @@ int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
* It issues a write ioctl given by
* \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
*/
-int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
- unsigned long size)
+drm_public int drmCommandWrite(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size)
{
unsigned long request;
@@ -2605,8 +2652,8 @@ int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
* It issues a read-write ioctl given by
* \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
*/
-int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
- unsigned long size)
+drm_public int drmCommandWriteRead(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size)
{
unsigned long request;
@@ -2628,14 +2675,13 @@ static struct {
static int nr_fds = 0;
-int drmOpenOnce(void *unused,
- const char *BusID,
- int *newlyopened)
+drm_public int drmOpenOnce(void *unused, const char *BusID, int *newlyopened)
{
return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY);
}
-int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type)
+drm_public int drmOpenOnceWithType(const char *BusID, int *newlyopened,
+ int type)
{
int i;
int fd;
@@ -2668,7 +2714,7 @@ int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type)
return fd;
}
-void drmCloseOnce(int fd)
+drm_public void drmCloseOnce(int fd)
{
int i;
@@ -2687,17 +2733,17 @@ void drmCloseOnce(int fd)
}
}
-int drmSetMaster(int fd)
+drm_public int drmSetMaster(int fd)
{
return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL);
}
-int drmDropMaster(int fd)
+drm_public int drmDropMaster(int fd)
{
return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL);
}
-char *drmGetDeviceNameFromFd(int fd)
+drm_public char *drmGetDeviceNameFromFd(int fd)
{
char name[128];
struct stat sbuf;
@@ -2723,7 +2769,21 @@ char *drmGetDeviceNameFromFd(int fd)
return strdup(name);
}
-int drmGetNodeTypeFromFd(int fd)
+static bool drmNodeIsDRM(int maj, int min)
+{
+#ifdef __linux__
+ char path[64];
+ struct stat sbuf;
+
+ snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/drm",
+ maj, min);
+ return stat(path, &sbuf) == 0;
+#else
+ return maj == DRM_MAJOR;
+#endif
+}
+
+drm_public int drmGetNodeTypeFromFd(int fd)
{
struct stat sbuf;
int maj, min, type;
@@ -2734,7 +2794,7 @@ int drmGetNodeTypeFromFd(int fd)
maj = major(sbuf.st_rdev);
min = minor(sbuf.st_rdev);
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) {
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode)) {
errno = EINVAL;
return -1;
}
@@ -2745,7 +2805,8 @@ int drmGetNodeTypeFromFd(int fd)
return type;
}
-int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
+drm_public int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags,
+ int *prime_fd)
{
struct drm_prime_handle args;
int ret;
@@ -2762,7 +2823,7 @@ int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
return 0;
}
-int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
+drm_public int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
{
struct drm_prime_handle args;
int ret;
@@ -2781,12 +2842,11 @@ static char *drmGetMinorNameForFD(int fd, int type)
{
#ifdef __linux__
DIR *sysdir;
- struct dirent *pent, *ent;
+ struct dirent *ent;
struct stat sbuf;
const char *name = drmGetMinorName(type);
int len;
char dev_name[64], buf[64];
- long name_max;
int maj, min;
if (!name)
@@ -2800,7 +2860,7 @@ static char *drmGetMinorNameForFD(int fd, int type)
maj = major(sbuf.st_rdev);
min = minor(sbuf.st_rdev);
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return NULL;
snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min);
@@ -2809,30 +2869,18 @@ static char *drmGetMinorNameForFD(int fd, int type)
if (!sysdir)
return NULL;
- name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX);
- if (name_max == -1)
- goto out_close_dir;
-
- pent = malloc(offsetof(struct dirent, d_name) + name_max + 1);
- if (pent == NULL)
- goto out_close_dir;
-
- while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) {
+ while ((ent = readdir(sysdir))) {
if (strncmp(ent->d_name, name, len) == 0) {
snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
ent->d_name);
- free(pent);
closedir(sysdir);
-
return strdup(dev_name);
}
}
- free(pent);
-
-out_close_dir:
closedir(sysdir);
+ return NULL;
#else
struct stat sbuf;
char buf[PATH_MAX + 1];
@@ -2846,7 +2894,7 @@ out_close_dir:
maj = major(sbuf.st_rdev);
min = minor(sbuf.st_rdev);
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return NULL;
switch (type) {
@@ -2873,15 +2921,14 @@ out_close_dir:
return strdup(buf);
#endif
- return NULL;
}
-char *drmGetPrimaryDeviceNameFromFd(int fd)
+drm_public char *drmGetPrimaryDeviceNameFromFd(int fd)
{
return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY);
}
-char *drmGetRenderDeviceNameFromFd(int fd)
+drm_public char *drmGetRenderDeviceNameFromFd(int fd)
{
return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
}
@@ -2930,12 +2977,26 @@ sysfs_uevent_get(const char *path, const char *fmt, ...)
}
#endif
+/* Little white lie to avoid major rework of the existing code */
+#define DRM_BUS_VIRTIO 0x10
+
static int drmParseSubsystemType(int maj, int min)
{
#ifdef __linux__
char path[PATH_MAX + 1];
char link[PATH_MAX + 1] = "";
char *name;
+ struct {
+ const char *name;
+ int bus_type;
+ } bus_types[] = {
+ { "/pci", DRM_BUS_PCI },
+ { "/usb", DRM_BUS_USB },
+ { "/platform", DRM_BUS_PLATFORM },
+ { "/spi", DRM_BUS_PLATFORM },
+ { "/host1x", DRM_BUS_HOST1X },
+ { "/virtio", DRM_BUS_VIRTIO },
+ };
snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/subsystem",
maj, min);
@@ -2947,20 +3008,13 @@ static int drmParseSubsystemType(int maj, int min)
if (!name)
return -EINVAL;
- if (strncmp(name, "/pci", 4) == 0)
- return DRM_BUS_PCI;
-
- if (strncmp(name, "/usb", 4) == 0)
- return DRM_BUS_USB;
-
- if (strncmp(name, "/platform", 9) == 0)
- return DRM_BUS_PLATFORM;
-
- if (strncmp(name, "/host1x", 7) == 0)
- return DRM_BUS_HOST1X;
+ for (unsigned i = 0; i < ARRAY_SIZE(bus_types); i++) {
+ if (strncmp(name, bus_types[i].name, strlen(bus_types[i].name)) == 0)
+ return bus_types[i].bus_type;
+ }
return -EINVAL;
-#elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__) || defined(__DragonFly__)
return DRM_BUS_PCI;
#else
#warning "Missing implementation of drmParseSubsystemType"
@@ -2968,16 +3022,32 @@ static int drmParseSubsystemType(int maj, int min)
#endif
}
+static void
+get_pci_path(int maj, int min, char *pci_path)
+{
+ char path[PATH_MAX + 1], *term;
+
+ snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+ if (!realpath(path, pci_path)) {
+ strcpy(pci_path, path);
+ return;
+ }
+
+ term = strrchr(pci_path, '/');
+ if (term && strncmp(term, "/virtio", 7) == 0)
+ *term = 0;
+}
+
static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
{
#ifdef __linux__
unsigned int domain, bus, dev, func;
- char path[PATH_MAX + 1], *value;
+ char pci_path[PATH_MAX + 1], *value;
int num;
- snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+ get_pci_path(maj, min, pci_path);
- value = sysfs_uevent_get(path, "PCI_SLOT_NAME");
+ value = sysfs_uevent_get(pci_path, "PCI_SLOT_NAME");
if (!value)
return -ENOENT;
@@ -2993,7 +3063,7 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
info->func = func;
return 0;
-#elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__) || defined(__DragonFly__)
struct drm_pciinfo pinfo;
int fd, type;
@@ -3023,32 +3093,32 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
#endif
}
-static int drmCompareBusInfo(drmDevicePtr a, drmDevicePtr b)
+drm_public int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b)
{
if (a == NULL || b == NULL)
- return -1;
+ return 0;
if (a->bustype != b->bustype)
- return -1;
+ return 0;
switch (a->bustype) {
case DRM_BUS_PCI:
- return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo));
+ return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo)) == 0;
case DRM_BUS_USB:
- return memcmp(a->businfo.usb, b->businfo.usb, sizeof(drmUsbBusInfo));
+ return memcmp(a->businfo.usb, b->businfo.usb, sizeof(drmUsbBusInfo)) == 0;
case DRM_BUS_PLATFORM:
- return memcmp(a->businfo.platform, b->businfo.platform, sizeof(drmPlatformBusInfo));
+ return memcmp(a->businfo.platform, b->businfo.platform, sizeof(drmPlatformBusInfo)) == 0;
case DRM_BUS_HOST1X:
- return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo));
+ return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo)) == 0;
default:
break;
}
- return -1;
+ return 0;
}
static int drmGetNodeType(const char *name)
@@ -3082,7 +3152,6 @@ static int parse_separate_sysfs_files(int maj, int min,
drmPciDeviceInfoPtr device,
bool ignore_revision)
{
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static const char *attrs[] = {
"revision", /* Older kernels are missing the file, so check for it first */
"vendor",
@@ -3090,14 +3159,15 @@ static int parse_separate_sysfs_files(int maj, int min,
"subsystem_vendor",
"subsystem_device",
};
- char path[PATH_MAX + 1];
+ char path[PATH_MAX + 1], pci_path[PATH_MAX + 1];
unsigned int data[ARRAY_SIZE(attrs)];
FILE *fp;
int ret;
+ get_pci_path(maj, min, pci_path);
+
for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) {
- snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/%s", maj, min,
- attrs[i]);
+ snprintf(path, PATH_MAX, "%s/%s", pci_path, attrs[i]);
fp = fopen(path, "r");
if (!fp)
return -errno;
@@ -3121,11 +3191,13 @@ static int parse_separate_sysfs_files(int maj, int min,
static int parse_config_sysfs_file(int maj, int min,
drmPciDeviceInfoPtr device)
{
- char path[PATH_MAX + 1];
+ char path[PATH_MAX + 1], pci_path[PATH_MAX + 1];
unsigned char config[64];
int fd, ret;
- snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/config", maj, min);
+ get_pci_path(maj, min, pci_path);
+
+ snprintf(path, PATH_MAX, "%s/config", pci_path);
fd = open(path, O_RDONLY);
if (fd < 0)
return -errno;
@@ -3157,7 +3229,7 @@ static int drmParsePciDeviceInfo(int maj, int min,
return parse_config_sysfs_file(maj, min, device);
return 0;
-#elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__) || defined(__DragonFly__)
struct drm_pciinfo pinfo;
int fd, type;
@@ -3220,7 +3292,7 @@ static void drmFreeHost1xDevice(drmDevicePtr device)
}
}
-void drmFreeDevice(drmDevicePtr *device)
+drm_public void drmFreeDevice(drmDevicePtr *device)
{
if (device == NULL)
return;
@@ -3241,7 +3313,7 @@ void drmFreeDevice(drmDevicePtr *device)
*device = NULL;
}
-void drmFreeDevices(drmDevicePtr devices[], int count)
+drm_public void drmFreeDevices(drmDevicePtr devices[], int count)
{
int i;
@@ -3652,6 +3724,53 @@ free_device:
return ret;
}
+static int
+process_device(drmDevicePtr *device, const char *d_name,
+ int req_subsystem_type,
+ bool fetch_deviceinfo, uint32_t flags)
+{
+ struct stat sbuf;
+ char node[PATH_MAX + 1];
+ int node_type, subsystem_type;
+ unsigned int maj, min;
+
+ node_type = drmGetNodeType(d_name);
+ if (node_type < 0)
+ return -1;
+
+ snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, d_name);
+ if (stat(node, &sbuf))
+ return -1;
+
+ maj = major(sbuf.st_rdev);
+ min = minor(sbuf.st_rdev);
+
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
+ return -1;
+
+ subsystem_type = drmParseSubsystemType(maj, min);
+ if (req_subsystem_type != -1 && req_subsystem_type != subsystem_type)
+ return -1;
+
+ switch (subsystem_type) {
+ case DRM_BUS_PCI:
+ case DRM_BUS_VIRTIO:
+ return drmProcessPciDevice(device, node, node_type, maj, min,
+ fetch_deviceinfo, flags);
+ case DRM_BUS_USB:
+ return drmProcessUsbDevice(device, node, node_type, maj, min,
+ fetch_deviceinfo, flags);
+ case DRM_BUS_PLATFORM:
+ return drmProcessPlatformDevice(device, node, node_type, maj, min,
+ fetch_deviceinfo, flags);
+ case DRM_BUS_HOST1X:
+ return drmProcessHost1xDevice(device, node, node_type, maj, min,
+ fetch_deviceinfo, flags);
+ default:
+ return -1;
+ }
+}
+
/* Consider devices located on the same bus as duplicate and fold the respective
* entries into a single one.
*
@@ -3663,7 +3782,7 @@ static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
for (i = 0; i < count; i++) {
for (j = i + 1; j < count; j++) {
- if (drmCompareBusInfo(local_devices[i], local_devices[j]) == 0) {
+ if (drmDevicesEqual(local_devices[i], local_devices[j])) {
local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
node_type = log2(local_devices[j]->available_nodes);
memcpy(local_devices[i]->nodes[node_type],
@@ -3681,6 +3800,28 @@ drm_device_validate_flags(uint32_t flags)
return (flags & ~DRM_DEVICE_GET_PCI_REVISION);
}
+static bool
+drm_device_has_rdev(drmDevicePtr device, dev_t find_rdev)
+{
+ struct stat sbuf;
+
+ for (int i = 0; i < DRM_NODE_MAX; i++) {
+ if (device->available_nodes & 1 << i) {
+ if (stat(device->nodes[i], &sbuf) == 0 &&
+ sbuf.st_rdev == find_rdev)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * The kernel drm core has a number of places that assume maximum of
+ * 3x64 devices nodes. That's 64 for each of primary, control and
+ * render nodes. Rounded it up to 256 for simplicity.
+ */
+#define MAX_DRM_NODES 256
+
/**
* Get information about the opened drm device
*
@@ -3694,7 +3835,7 @@ drm_device_validate_flags(uint32_t flags)
* \note Unlike drmGetDevice it does not retrieve the pci device revision field
* unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set.
*/
-int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
+drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
{
#ifdef __OpenBSD__
/*
@@ -3718,7 +3859,7 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
maj = major(sbuf.st_rdev);
min = minor(sbuf.st_rdev);
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return -EINVAL;
node_type = drmGetMinorType(min);
@@ -3761,16 +3902,14 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
return 0;
#else
- drmDevicePtr *local_devices;
+ drmDevicePtr local_devices[MAX_DRM_NODES];
drmDevicePtr d;
DIR *sysdir;
struct dirent *dent;
struct stat sbuf;
- char node[PATH_MAX + 1];
- int node_type, subsystem_type;
+ int subsystem_type;
int maj, min;
int ret, i, node_count;
- int max_count = 16;
dev_t find_rdev;
if (drm_device_validate_flags(flags))
@@ -3786,112 +3925,52 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
maj = major(sbuf.st_rdev);
min = minor(sbuf.st_rdev);
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return -EINVAL;
subsystem_type = drmParseSubsystemType(maj, min);
-
- local_devices = calloc(max_count, sizeof(drmDevicePtr));
- if (local_devices == NULL)
- return -ENOMEM;
+ if (subsystem_type < 0)
+ return subsystem_type;
sysdir = opendir(DRM_DIR_NAME);
- if (!sysdir) {
- ret = -errno;
- goto free_locals;
- }
+ if (!sysdir)
+ return -errno;
i = 0;
while ((dent = readdir(sysdir))) {
- node_type = drmGetNodeType(dent->d_name);
- if (node_type < 0)
- continue;
-
- snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
- if (stat(node, &sbuf))
- continue;
-
- maj = major(sbuf.st_rdev);
- min = minor(sbuf.st_rdev);
-
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
- continue;
-
- if (drmParseSubsystemType(maj, min) != subsystem_type)
+ ret = process_device(&d, dent->d_name, subsystem_type, true, flags);
+ if (ret)
continue;
- switch (subsystem_type) {
- case DRM_BUS_PCI:
- ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags);
- if (ret)
- continue;
-
+ if (i >= MAX_DRM_NODES) {
+ fprintf(stderr, "More than %d drm nodes detected. "
+ "Please report a bug - that should not happen.\n"
+ "Skipping extra nodes\n", MAX_DRM_NODES);
break;
-
- case DRM_BUS_USB:
- ret = drmProcessUsbDevice(&d, node, node_type, maj, min, true, flags);
- if (ret)
- continue;
-
- break;
-
- case DRM_BUS_PLATFORM:
- ret = drmProcessPlatformDevice(&d, node, node_type, maj, min, true, flags);
- if (ret)
- continue;
-
- break;
-
- case DRM_BUS_HOST1X:
- ret = drmProcessHost1xDevice(&d, node, node_type, maj, min, true, flags);
- if (ret)
- continue;
-
- break;
-
- default:
- continue;
}
-
- if (i >= max_count) {
- drmDevicePtr *temp;
-
- max_count += 16;
- temp = realloc(local_devices, max_count * sizeof(drmDevicePtr));
- if (!temp)
- goto free_devices;
- local_devices = temp;
- }
-
- /* store target at local_devices[0] for ease to use below */
- if (find_rdev == sbuf.st_rdev && i) {
- local_devices[i] = local_devices[0];
- local_devices[0] = d;
- }
- else
- local_devices[i] = d;
+ local_devices[i] = d;
i++;
}
node_count = i;
drmFoldDuplicatedDevices(local_devices, node_count);
- *device = local_devices[0];
- drmFreeDevices(&local_devices[1], node_count - 1);
+ *device = NULL;
+
+ for (i = 0; i < node_count; i++) {
+ if (!local_devices[i])
+ continue;
+
+ if (drm_device_has_rdev(local_devices[i], find_rdev))
+ *device = local_devices[i];
+ else
+ drmFreeDevice(&local_devices[i]);
+ }
closedir(sysdir);
- free(local_devices);
if (*device == NULL)
return -ENODEV;
return 0;
-
-free_devices:
- drmFreeDevices(local_devices, i);
- closedir(sysdir);
-
-free_locals:
- free(local_devices);
- return ret;
#endif
}
@@ -3904,7 +3983,7 @@ free_locals:
*
* \return zero on success, negative error code otherwise.
*/
-int drmGetDevice(int fd, drmDevicePtr *device)
+drm_public int drmGetDevice(int fd, drmDevicePtr *device)
{
return drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, device);
}
@@ -3925,100 +4004,34 @@ int drmGetDevice(int fd, drmDevicePtr *device)
* \note Unlike drmGetDevices it does not retrieve the pci device revision field
* unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set.
*/
-int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices)
+drm_public int drmGetDevices2(uint32_t flags, drmDevicePtr devices[],
+ int max_devices)
{
- drmDevicePtr *local_devices;
+ drmDevicePtr local_devices[MAX_DRM_NODES];
drmDevicePtr device;
DIR *sysdir;
struct dirent *dent;
- struct stat sbuf;
- char node[PATH_MAX + 1];
- int node_type, subsystem_type;
- int maj, min;
int ret, i, node_count, device_count;
- int max_count = 16;
if (drm_device_validate_flags(flags))
return -EINVAL;
- local_devices = calloc(max_count, sizeof(drmDevicePtr));
- if (local_devices == NULL)
- return -ENOMEM;
-
sysdir = opendir(DRM_DIR_NAME);
- if (!sysdir) {
- ret = -errno;
- goto free_locals;
- }
+ if (!sysdir)
+ return -errno;
i = 0;
while ((dent = readdir(sysdir))) {
- node_type = drmGetNodeType(dent->d_name);
- if (node_type < 0)
- continue;
-
- snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
- if (stat(node, &sbuf))
- continue;
-
- maj = major(sbuf.st_rdev);
- min = minor(sbuf.st_rdev);
-
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
- continue;
-
- subsystem_type = drmParseSubsystemType(maj, min);
-
- if (subsystem_type < 0)
+ ret = process_device(&device, dent->d_name, -1, devices != NULL, flags);
+ if (ret)
continue;
- switch (subsystem_type) {
- case DRM_BUS_PCI:
- ret = drmProcessPciDevice(&device, node, node_type,
- maj, min, devices != NULL, flags);
- if (ret)
- continue;
-
+ if (i >= MAX_DRM_NODES) {
+ fprintf(stderr, "More than %d drm nodes detected. "
+ "Please report a bug - that should not happen.\n"
+ "Skipping extra nodes\n", MAX_DRM_NODES);
break;
-
- case DRM_BUS_USB:
- ret = drmProcessUsbDevice(&device, node, node_type, maj, min,
- devices != NULL, flags);
- if (ret)
- goto free_devices;
-
- break;
-
- case DRM_BUS_PLATFORM:
- ret = drmProcessPlatformDevice(&device, node, node_type, maj, min,
- devices != NULL, flags);
- if (ret)
- goto free_devices;
-
- break;
-
- case DRM_BUS_HOST1X:
- ret = drmProcessHost1xDevice(&device, node, node_type, maj, min,
- devices != NULL, flags);
- if (ret)
- goto free_devices;
-
- break;
-
- default:
- continue;
}
-
- if (i >= max_count) {
- drmDevicePtr *temp;
-
- max_count += 16;
- temp = realloc(local_devices, max_count * sizeof(drmDevicePtr));
- if (!temp)
- goto free_devices;
- local_devices = temp;
- }
-
local_devices[i] = device;
i++;
}
@@ -4040,16 +4053,7 @@ int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices)
}
closedir(sysdir);
- free(local_devices);
return device_count;
-
-free_devices:
- drmFreeDevices(local_devices, i);
- closedir(sysdir);
-
-free_locals:
- free(local_devices);
- return ret;
}
/**
@@ -4064,12 +4068,12 @@ free_locals:
* alternatively the number of devices stored in devices[], which is
* capped by the max_devices.
*/
-int drmGetDevices(drmDevicePtr devices[], int max_devices)
+drm_public int drmGetDevices(drmDevicePtr devices[], int max_devices)
{
return drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devices, max_devices);
}
-char *drmGetDeviceNameFromFd2(int fd)
+drm_public char *drmGetDeviceNameFromFd2(int fd)
{
#ifdef __linux__
struct stat sbuf;
@@ -4082,7 +4086,7 @@ char *drmGetDeviceNameFromFd2(int fd)
maj = major(sbuf.st_rdev);
min = minor(sbuf.st_rdev);
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return NULL;
snprintf(path, sizeof(path), "/sys/dev/char/%d:%d", maj, min);
@@ -4108,7 +4112,7 @@ char *drmGetDeviceNameFromFd2(int fd)
maj = major(sbuf.st_rdev);
min = minor(sbuf.st_rdev);
- if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return NULL;
node_type = drmGetMinorType(min);
@@ -4140,3 +4144,136 @@ char *drmGetDeviceNameFromFd2(int fd)
return strdup(node);
#endif
}
+
+drm_public int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle)
+{
+ struct drm_syncobj_create args;
+ int ret;
+
+ memclear(args);
+ args.flags = flags;
+ args.handle = 0;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &args);
+ if (ret)
+ return ret;
+ *handle = args.handle;
+ return 0;
+}
+
+drm_public int drmSyncobjDestroy(int fd, uint32_t handle)
+{
+ struct drm_syncobj_destroy args;
+
+ memclear(args);
+ args.handle = handle;
+ return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &args);
+}
+
+drm_public int drmSyncobjHandleToFD(int fd, uint32_t handle, int *obj_fd)
+{
+ struct drm_syncobj_handle args;
+ int ret;
+
+ memclear(args);
+ args.fd = -1;
+ args.handle = handle;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &args);
+ if (ret)
+ return ret;
+ *obj_fd = args.fd;
+ return 0;
+}
+
+drm_public int drmSyncobjFDToHandle(int fd, int obj_fd, uint32_t *handle)
+{
+ struct drm_syncobj_handle args;
+ int ret;
+
+ memclear(args);
+ args.fd = obj_fd;
+ args.handle = 0;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &args);
+ if (ret)
+ return ret;
+ *handle = args.handle;
+ return 0;
+}
+
+drm_public int drmSyncobjImportSyncFile(int fd, uint32_t handle,
+ int sync_file_fd)
+{
+ struct drm_syncobj_handle args;
+
+ memclear(args);
+ args.fd = sync_file_fd;
+ args.handle = handle;
+ args.flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE;
+ return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &args);
+}
+
+drm_public int drmSyncobjExportSyncFile(int fd, uint32_t handle,
+ int *sync_file_fd)
+{
+ struct drm_syncobj_handle args;
+ int ret;
+
+ memclear(args);
+ args.fd = -1;
+ args.handle = handle;
+ args.flags = DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &args);
+ if (ret)
+ return ret;
+ *sync_file_fd = args.fd;
+ return 0;
+}
+
+drm_public int drmSyncobjWait(int fd, uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+ struct drm_syncobj_wait args;
+ int ret;
+
+ memclear(args);
+ args.handles = (uintptr_t)handles;
+ args.timeout_nsec = timeout_nsec;
+ args.count_handles = num_handles;
+ args.flags = flags;
+
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &args);
+ if (ret < 0)
+ return -errno;
+
+ if (first_signaled)
+ *first_signaled = args.first_signaled;
+ return ret;
+}
+
+drm_public int drmSyncobjReset(int fd, const uint32_t *handles,
+ uint32_t handle_count)
+{
+ struct drm_syncobj_array args;
+ int ret;
+
+ memclear(args);
+ args.handles = (uintptr_t)handles;
+ args.count_handles = handle_count;
+
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_RESET, &args);
+ return ret;
+}
+
+drm_public int drmSyncobjSignal(int fd, const uint32_t *handles,
+ uint32_t handle_count)
+{
+ struct drm_syncobj_array args;
+ int ret;
+
+ memclear(args);
+ args.handles = (uintptr_t)handles;
+ args.count_handles = handle_count;
+
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &args);
+ return ret;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 0d927018..7773d71a 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -636,6 +636,12 @@ extern int drmCtlUninstHandler(int fd);
extern int drmSetClientCap(int fd, uint64_t capability,
uint64_t value);
+extern int drmCrtcGetSequence(int fd, uint32_t crtcId,
+ uint64_t *sequence, uint64_t *ns);
+extern int drmCrtcQueueSequence(int fd, uint32_t crtcId,
+ uint32_t flags, uint64_t sequence,
+ uint64_t *sequence_queued,
+ uint64_t user_data);
/* General user-level programmer's API: authenticated client and/or X */
extern int drmMap(int fd,
drm_handle_t handle,
@@ -728,7 +734,7 @@ extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2);
extern int drmSetMaster(int fd);
extern int drmDropMaster(int fd);
-#define DRM_EVENT_CONTEXT_VERSION 2
+#define DRM_EVENT_CONTEXT_VERSION 4
typedef struct _drmEventContext {
@@ -748,6 +754,17 @@ typedef struct _drmEventContext {
unsigned int tv_usec,
void *user_data);
+ void (*page_flip_handler2)(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ unsigned int crtc_id,
+ void *user_data);
+
+ void (*sequence_handler)(int fd,
+ uint64_t sequence,
+ uint64_t ns,
+ uint64_t user_data);
} drmEventContext, *drmEventContextPtr;
extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
@@ -844,6 +861,21 @@ extern void drmFreeDevices(drmDevicePtr devices[], int count);
extern int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device);
extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices);
+extern int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b);
+
+extern int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle);
+extern int drmSyncobjDestroy(int fd, uint32_t handle);
+extern int drmSyncobjHandleToFD(int fd, uint32_t handle, int *obj_fd);
+extern int drmSyncobjFDToHandle(int fd, int obj_fd, uint32_t *handle);
+
+extern int drmSyncobjImportSyncFile(int fd, uint32_t handle, int sync_file_fd);
+extern int drmSyncobjExportSyncFile(int fd, uint32_t handle, int *sync_file_fd);
+extern int drmSyncobjWait(int fd, uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t handle_count);
+extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t handle_count);
+
#if defined(__cplusplus)
}
#endif
diff --git a/xf86drmHash.c b/xf86drmHash.c
index f287e61f..2cf2b80e 100644
--- a/xf86drmHash.c
+++ b/xf86drmHash.c
@@ -71,6 +71,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "libdrm_macros.h"
#include "xf86drm.h"
#include "xf86drmHash.h"
@@ -98,30 +99,21 @@ static unsigned long HashHash(unsigned long key)
}
hash %= HASH_SIZE;
-#if DEBUG
- printf( "Hash(%lu) = %lu\n", key, hash);
-#endif
return hash;
}
-void *drmHashCreate(void)
+drm_public void *drmHashCreate(void)
{
HashTablePtr table;
- int i;
table = drmMalloc(sizeof(*table));
if (!table) return NULL;
table->magic = HASH_MAGIC;
- table->entries = 0;
- table->hits = 0;
- table->partials = 0;
- table->misses = 0;
- for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
return table;
}
-int drmHashDestroy(void *t)
+drm_public int drmHashDestroy(void *t)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
@@ -172,7 +164,7 @@ static HashBucketPtr HashFind(HashTablePtr table,
return NULL;
}
-int drmHashLookup(void *t, unsigned long key, void **value)
+drm_public int drmHashLookup(void *t, unsigned long key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
@@ -185,7 +177,7 @@ int drmHashLookup(void *t, unsigned long key, void **value)
return 0; /* Found */
}
-int drmHashInsert(void *t, unsigned long key, void *value)
+drm_public int drmHashInsert(void *t, unsigned long key, void *value)
{
HashTablePtr table = (HashTablePtr)t;
HashBucketPtr bucket;
@@ -201,13 +193,10 @@ int drmHashInsert(void *t, unsigned long key, void *value)
bucket->value = value;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
-#if DEBUG
- printf("Inserted %lu at %lu/%p\n", key, hash, bucket);
-#endif
return 0; /* Added to table */
}
-int drmHashDelete(void *t, unsigned long key)
+drm_public int drmHashDelete(void *t, unsigned long key)
{
HashTablePtr table = (HashTablePtr)t;
unsigned long hash;
@@ -224,7 +213,7 @@ int drmHashDelete(void *t, unsigned long key)
return 0;
}
-int drmHashNext(void *t, unsigned long *key, void **value)
+drm_public int drmHashNext(void *t, unsigned long *key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
@@ -241,7 +230,7 @@ int drmHashNext(void *t, unsigned long *key, void **value)
return 0;
}
-int drmHashFirst(void *t, unsigned long *key, void **value)
+drm_public int drmHashFirst(void *t, unsigned long *key, void **value)
{
HashTablePtr table = (HashTablePtr)t;
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 2876b422..c878d9ea 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -38,10 +38,6 @@
* platforms find which headers to include to get uint32_t
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
@@ -52,6 +48,7 @@
#include <stdio.h>
#include <stdbool.h>
+#include "libdrm_macros.h"
#include "xf86drmMode.h"
#include "xf86drm.h"
#include <drm.h>
@@ -96,7 +93,7 @@ static void* drmAllocCpy(char *array, int count, int entry_size)
* A couple of free functions.
*/
-void drmModeFreeModeInfo(drmModeModeInfoPtr ptr)
+drm_public void drmModeFreeModeInfo(drmModeModeInfoPtr ptr)
{
if (!ptr)
return;
@@ -104,7 +101,7 @@ void drmModeFreeModeInfo(drmModeModeInfoPtr ptr)
drmFree(ptr);
}
-void drmModeFreeResources(drmModeResPtr ptr)
+drm_public void drmModeFreeResources(drmModeResPtr ptr)
{
if (!ptr)
return;
@@ -116,7 +113,7 @@ void drmModeFreeResources(drmModeResPtr ptr)
drmFree(ptr);
}
-void drmModeFreeFB(drmModeFBPtr ptr)
+drm_public void drmModeFreeFB(drmModeFBPtr ptr)
{
if (!ptr)
return;
@@ -125,7 +122,7 @@ void drmModeFreeFB(drmModeFBPtr ptr)
drmFree(ptr);
}
-void drmModeFreeCrtc(drmModeCrtcPtr ptr)
+drm_public void drmModeFreeCrtc(drmModeCrtcPtr ptr)
{
if (!ptr)
return;
@@ -133,7 +130,7 @@ void drmModeFreeCrtc(drmModeCrtcPtr ptr)
drmFree(ptr);
}
-void drmModeFreeConnector(drmModeConnectorPtr ptr)
+drm_public void drmModeFreeConnector(drmModeConnectorPtr ptr)
{
if (!ptr)
return;
@@ -145,7 +142,7 @@ void drmModeFreeConnector(drmModeConnectorPtr ptr)
drmFree(ptr);
}
-void drmModeFreeEncoder(drmModeEncoderPtr ptr)
+drm_public void drmModeFreeEncoder(drmModeEncoderPtr ptr)
{
drmFree(ptr);
}
@@ -154,7 +151,7 @@ void drmModeFreeEncoder(drmModeEncoderPtr ptr)
* ModeSetting functions.
*/
-drmModeResPtr drmModeGetResources(int fd)
+drm_public drmModeResPtr drmModeGetResources(int fd)
{
struct drm_mode_card_res res, counts;
drmModeResPtr r = 0;
@@ -248,9 +245,10 @@ err_allocs:
return r;
}
-int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
- uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
- uint32_t *buf_id)
+
+drm_public int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
+ uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
+ uint32_t *buf_id)
{
struct drm_mode_fb_cmd f;
int ret;
@@ -270,10 +268,10 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
return 0;
}
-int drmModeAddFB2WithModifiers(int fd, uint32_t width, uint32_t height,
- uint32_t pixel_format, uint32_t bo_handles[4],
- uint32_t pitches[4], uint32_t offsets[4],
- uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)
+drm_public int drmModeAddFB2WithModifiers(int fd, uint32_t width,
+ uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
+ const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)
{
struct drm_mode_fb_cmd2 f;
int ret;
@@ -296,10 +294,10 @@ int drmModeAddFB2WithModifiers(int fd, uint32_t width, uint32_t height,
return 0;
}
-int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
- uint32_t pixel_format, uint32_t bo_handles[4],
- uint32_t pitches[4], uint32_t offsets[4],
- uint32_t *buf_id, uint32_t flags)
+drm_public int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
+ uint32_t *buf_id, uint32_t flags)
{
return drmModeAddFB2WithModifiers(fd, width, height,
pixel_format, bo_handles,
@@ -307,12 +305,12 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
buf_id, flags);
}
-int drmModeRmFB(int fd, uint32_t bufferId)
+drm_public int drmModeRmFB(int fd, uint32_t bufferId)
{
return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
}
-drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
+drm_public drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
{
struct drm_mode_fb_cmd info;
drmModeFBPtr r;
@@ -337,7 +335,7 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
return r;
}
-int drmModeDirtyFB(int fd, uint32_t bufferId,
+drm_public int drmModeDirtyFB(int fd, uint32_t bufferId,
drmModeClipPtr clips, uint32_t num_clips)
{
struct drm_mode_fb_dirty_cmd dirty;
@@ -354,7 +352,7 @@ int drmModeDirtyFB(int fd, uint32_t bufferId,
* Crtc functions
*/
-drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
+drm_public drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
{
struct drm_mode_crtc crtc;
drmModeCrtcPtr r;
@@ -386,7 +384,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
return r;
}
-int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
+drm_public int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
uint32_t x, uint32_t y, uint32_t *connectors, int count,
drmModeModeInfoPtr mode)
{
@@ -411,7 +409,8 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
* Cursor manipulation
*/
-int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height)
+drm_public int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle,
+ uint32_t width, uint32_t height)
{
struct drm_mode_cursor arg;
@@ -425,7 +424,9 @@ int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width
return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg);
}
-int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y)
+drm_public int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle,
+ uint32_t width, uint32_t height, int32_t hot_x,
+ int32_t hot_y)
{
struct drm_mode_cursor2 arg;
@@ -441,7 +442,7 @@ int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t widt
return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR2, &arg);
}
-int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
+drm_public int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
{
struct drm_mode_cursor arg;
@@ -457,7 +458,7 @@ int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
/*
* Encoder get
*/
-drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
+drm_public drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
{
struct drm_mode_get_encoder enc;
drmModeEncoderPtr r = NULL;
@@ -589,17 +590,17 @@ err_allocs:
return r;
}
-drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
+drm_public drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
{
return _drmModeGetConnector(fd, connector_id, 1);
}
-drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
+drm_public drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
{
return _drmModeGetConnector(fd, connector_id, 0);
}
-int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
+drm_public int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
{
struct drm_mode_mode_cmd res;
@@ -610,7 +611,7 @@ int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf
return DRM_IOCTL(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
}
-int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
+drm_public int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
{
struct drm_mode_mode_cmd res;
@@ -621,7 +622,7 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf
return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
}
-drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
+drm_public drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
{
struct drm_mode_get_property prop;
drmModePropertyPtr r;
@@ -675,7 +676,7 @@ err_allocs:
return r;
}
-void drmModeFreeProperty(drmModePropertyPtr ptr)
+drm_public void drmModeFreeProperty(drmModePropertyPtr ptr)
{
if (!ptr)
return;
@@ -685,7 +686,8 @@ void drmModeFreeProperty(drmModePropertyPtr ptr)
drmFree(ptr);
}
-drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
+drm_public drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd,
+ uint32_t blob_id)
{
struct drm_mode_get_blob blob;
drmModePropertyBlobPtr r;
@@ -716,7 +718,7 @@ err_allocs:
return r;
}
-void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
+drm_public void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
{
if (!ptr)
return;
@@ -725,8 +727,9 @@ void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
drmFree(ptr);
}
-int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id,
- uint64_t value)
+drm_public int drmModeConnectorSetProperty(int fd, uint32_t connector_id,
+ uint32_t property_id,
+ uint64_t value)
{
struct drm_mode_connector_set_property osp;
@@ -744,7 +747,7 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property
* -EINVAL or invalid bus id
* -ENOSYS if no modesetting support
*/
-int drmCheckModesettingSupported(const char *busid)
+drm_public int drmCheckModesettingSupported(const char *busid)
{
#if defined (__linux__)
char pci_dev_dir[1024];
@@ -831,8 +834,7 @@ int drmCheckModesettingSupported(const char *busid)
}
#elif defined(__DragonFly__)
return 0;
-#endif
-#ifdef __OpenBSD__
+#elif defined(__OpenBSD__)
int fd;
struct drm_mode_card_res res;
drmModeResPtr r = 0;
@@ -853,8 +855,9 @@ int drmCheckModesettingSupported(const char *busid)
return -ENOSYS;
}
-int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
- uint16_t *red, uint16_t *green, uint16_t *blue)
+drm_public int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
+ uint16_t *red, uint16_t *green,
+ uint16_t *blue)
{
struct drm_mode_crtc_lut l;
@@ -868,8 +871,9 @@ int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
return DRM_IOCTL(fd, DRM_IOCTL_MODE_GETGAMMA, &l);
}
-int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
- uint16_t *red, uint16_t *green, uint16_t *blue)
+drm_public int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
+ uint16_t *red, uint16_t *green,
+ uint16_t *blue)
{
struct drm_mode_crtc_lut l;
@@ -883,12 +887,14 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETGAMMA, &l);
}
-int drmHandleEvent(int fd, drmEventContextPtr evctx)
+drm_public int drmHandleEvent(int fd, drmEventContextPtr evctx)
{
char buffer[1024];
int len, i;
struct drm_event *e;
struct drm_event_vblank *vblank;
+ struct drm_event_crtc_sequence *seq;
+ void *user_data;
/* The DRM read semantics guarantees that we always get only
* complete events. */
@@ -915,15 +921,30 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
U642VOID (vblank->user_data));
break;
case DRM_EVENT_FLIP_COMPLETE:
- if (evctx->version < 2 ||
- evctx->page_flip_handler == NULL)
- break;
vblank = (struct drm_event_vblank *) e;
- evctx->page_flip_handler(fd,
- vblank->sequence,
- vblank->tv_sec,
- vblank->tv_usec,
- U642VOID (vblank->user_data));
+ user_data = U642VOID (vblank->user_data);
+
+ if (evctx->version >= 3 && evctx->page_flip_handler2)
+ evctx->page_flip_handler2(fd,
+ vblank->sequence,
+ vblank->tv_sec,
+ vblank->tv_usec,
+ vblank->crtc_id,
+ user_data);
+ else if (evctx->version >= 2 && evctx->page_flip_handler)
+ evctx->page_flip_handler(fd,
+ vblank->sequence,
+ vblank->tv_sec,
+ vblank->tv_usec,
+ user_data);
+ break;
+ case DRM_EVENT_CRTC_SEQUENCE:
+ seq = (struct drm_event_crtc_sequence *) e;
+ if (evctx->version >= 4 && evctx->sequence_handler)
+ evctx->sequence_handler(fd,
+ seq->sequence,
+ seq->time_ns,
+ seq->user_data);
break;
default:
break;
@@ -934,7 +955,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
return 0;
}
-int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
+drm_public int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
uint32_t flags, void *user_data)
{
struct drm_mode_crtc_page_flip flip;
@@ -948,7 +969,7 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
}
-int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
+drm_public int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
uint32_t flags, void *user_data,
uint32_t target_vblank)
{
@@ -964,7 +985,7 @@ int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip_target);
}
-int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
+drm_public int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
uint32_t fb_id, uint32_t flags,
int32_t crtc_x, int32_t crtc_y,
uint32_t crtc_w, uint32_t crtc_h,
@@ -990,7 +1011,7 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s);
}
-drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
+drm_public drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
{
struct drm_mode_get_plane ovr, counts;
drmModePlanePtr r = 0;
@@ -1041,7 +1062,7 @@ err_allocs:
return r;
}
-void drmModeFreePlane(drmModePlanePtr ptr)
+drm_public void drmModeFreePlane(drmModePlanePtr ptr)
{
if (!ptr)
return;
@@ -1050,7 +1071,7 @@ void drmModeFreePlane(drmModePlanePtr ptr)
drmFree(ptr);
}
-drmModePlaneResPtr drmModeGetPlaneResources(int fd)
+drm_public drmModePlaneResPtr drmModeGetPlaneResources(int fd)
{
struct drm_mode_get_plane_res res, counts;
drmModePlaneResPtr r = 0;
@@ -1095,7 +1116,7 @@ err_allocs:
return r;
}
-void drmModeFreePlaneResources(drmModePlaneResPtr ptr)
+drm_public void drmModeFreePlaneResources(drmModePlaneResPtr ptr)
{
if (!ptr)
return;
@@ -1104,7 +1125,7 @@ void drmModeFreePlaneResources(drmModePlaneResPtr ptr)
drmFree(ptr);
}
-drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd,
+drm_public drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd,
uint32_t object_id,
uint32_t object_type)
{
@@ -1165,7 +1186,7 @@ err_allocs:
return ret;
}
-void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr)
+drm_public void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr)
{
if (!ptr)
return;
@@ -1174,7 +1195,7 @@ void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr)
drmFree(ptr);
}
-int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
+drm_public int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
uint32_t property_id, uint64_t value)
{
struct drm_mode_obj_set_property prop;
@@ -1188,275 +1209,6 @@ int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop);
}
-typedef struct _drmModePropertySetItem drmModePropertySetItem, *drmModePropertySetItemPtr;
-
-struct _drmModePropertySetItem {
- uint32_t object_id;
- uint32_t property_id;
- bool is_blob;
- uint64_t value;
- void *blob;
- drmModePropertySetItemPtr next;
-};
-
-struct _drmModePropertySet {
- unsigned int count_objs;
- unsigned int count_props;
- unsigned int count_blobs;
- drmModePropertySetItem list;
-};
-
-drmModePropertySetPtr drmModePropertySetAlloc(void)
-{
- drmModePropertySetPtr set;
-
- set = drmMalloc(sizeof *set);
- if (!set)
- return NULL;
-
- set->list.next = NULL;
- set->count_props = 0;
- set->count_objs = 0;
-
- return set;
-}
-
-int drmModePropertySetAdd(drmModePropertySetPtr set,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t value)
-{
- drmModePropertySetItemPtr prev = &set->list;
- bool new_obj = false;
-
- /* keep it sorted by object_id and property_id */
- while (prev->next) {
- if (prev->next->object_id > object_id)
- break;
-
- if (prev->next->object_id == object_id &&
- prev->next->property_id >= property_id)
- break;
-
- prev = prev->next;
- }
-
- if ((prev == &set->list || prev->object_id != object_id) &&
- (!prev->next || prev->next->object_id != object_id))
- new_obj = true;
-
- /* replace or add? */
- if (prev->next &&
- prev->next->object_id == object_id &&
- prev->next->property_id == property_id) {
- drmModePropertySetItemPtr item = prev->next;
-
- if (item->is_blob)
- return -EINVAL;
-
- item->value = value;
- } else {
- drmModePropertySetItemPtr item;
-
- item = drmMalloc(sizeof *item);
- if (!item)
- return -1;
-
- item->object_id = object_id;
- item->property_id = property_id;
- item->value = value;
- item->is_blob = false;
- item->blob = NULL;
-
- item->next = prev->next;
- prev->next = item;
-
- set->count_props++;
- }
-
- if (new_obj)
- set->count_objs++;
-
- return 0;
-}
-
-int drmModePropertySetAddBlob(drmModePropertySetPtr set,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t length,
- void *data)
-{
- drmModePropertySetItemPtr prev = &set->list;
- bool new_obj = false;
-
- /* keep it sorted by object_id and property_id */
- while (prev->next) {
- if (prev->next->object_id > object_id)
- break;
-
- if (prev->next->object_id == object_id &&
- prev->next->property_id >= property_id)
- break;
-
- prev = prev->next;
- }
-
- if ((prev == &set->list || prev->object_id != object_id) &&
- (!prev->next || prev->next->object_id != object_id))
- new_obj = true;
-
- /* replace or add? */
- if (prev->next &&
- prev->next->object_id == object_id &&
- prev->next->property_id == property_id) {
- drmModePropertySetItemPtr item = prev->next;
-
- if (!item->is_blob)
- return -EINVAL;
-
- item->value = length;
- item->blob = data;
- } else {
- drmModePropertySetItemPtr item;
-
- item = drmMalloc(sizeof *item);
- if (!item)
- return -1;
-
- item->object_id = object_id;
- item->property_id = property_id;
- item->is_blob = true;
- item->value = length;
- item->blob = data;
-
- item->next = prev->next;
- prev->next = item;
-
- set->count_props++;
- set->count_blobs++;
- }
-
- if (new_obj)
- set->count_objs++;
-
- return 0;
-}
-
-void drmModePropertySetFree(drmModePropertySetPtr set)
-{
- drmModePropertySetItemPtr item;
-
- if (!set)
- return;
-
- item = set->list.next;
-
- while (item) {
- drmModePropertySetItemPtr next = item->next;
-
- drmFree(item);
-
- item = next;
- }
-
- drmFree(set);
-}
-
-int drmModePropertySetCommit(int fd, uint32_t flags, void *user_data,
- drmModePropertySetPtr set)
-{
- drmModePropertySetItemPtr item;
- uint32_t *objs_ptr = NULL;
- uint32_t *count_props_ptr = NULL;
- uint32_t *props_ptr = NULL;
- uint64_t *prop_values_ptr = NULL;
- uint64_t *blob_values_ptr = NULL;
- struct drm_mode_atomic atomic = { 0 };
- unsigned int obj_idx = 0;
- unsigned int prop_idx = 0;
- unsigned int blob_idx = 0;
- int ret = -1;
-
- if (!set)
- return -1;
-
- objs_ptr = drmMalloc(set->count_objs * sizeof objs_ptr[0]);
- if (!objs_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- count_props_ptr = drmMalloc(set->count_objs * sizeof count_props_ptr[0]);
- if (!count_props_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- props_ptr = drmMalloc(set->count_props * sizeof props_ptr[0]);
- if (!props_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- prop_values_ptr = drmMalloc(set->count_props * sizeof prop_values_ptr[0]);
- if (!prop_values_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- blob_values_ptr = drmMalloc(set->count_blobs * sizeof blob_values_ptr[0]);
- if (!blob_values_ptr) {
- errno = ENOMEM;
- goto out;
- }
-
- item = set->list.next;
-
- while (item) {
- int count_props = 0;
- drmModePropertySetItemPtr next = item;
-
- objs_ptr[obj_idx] = item->object_id;
-
- while (next && next->object_id == item->object_id) {
- props_ptr[prop_idx] = next->property_id;
- prop_values_ptr[prop_idx] = next->value;
- prop_idx++;
-
- if (next->is_blob)
- blob_values_ptr[blob_idx++] = VOID2U64(next->blob);
-
- count_props++;
-
- next = next->next;
- }
-
- count_props_ptr[obj_idx++] = count_props;
-
- item = next;
- }
-
- atomic.count_objs = set->count_objs;
- atomic.flags = flags;
- atomic.objs_ptr = VOID2U64(objs_ptr);
- atomic.count_props_ptr = VOID2U64(count_props_ptr);
- atomic.props_ptr = VOID2U64(props_ptr);
- atomic.prop_values_ptr = VOID2U64(prop_values_ptr);
-// TODO:
-// atomic.blob_values_ptr = VOID2U64(blob_values_ptr);
- atomic.user_data = VOID2U64(user_data);
-
- ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic);
-
-out:
- drmFree(objs_ptr);
- drmFree(count_props_ptr);
- drmFree(props_ptr);
- drmFree(prop_values_ptr);
-
- return ret;
-}
-
typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr;
struct _drmModeAtomicReqItem {
@@ -1471,7 +1223,7 @@ struct _drmModeAtomicReq {
drmModeAtomicReqItemPtr items;
};
-drmModeAtomicReqPtr drmModeAtomicAlloc(void)
+drm_public drmModeAtomicReqPtr drmModeAtomicAlloc(void)
{
drmModeAtomicReqPtr req;
@@ -1486,7 +1238,7 @@ drmModeAtomicReqPtr drmModeAtomicAlloc(void)
return req;
}
-drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
+drm_public drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
{
drmModeAtomicReqPtr new;
@@ -1515,7 +1267,8 @@ drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
return new;
}
-int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment)
+drm_public int drmModeAtomicMerge(drmModeAtomicReqPtr base,
+ drmModeAtomicReqPtr augment)
{
if (!base)
return -EINVAL;
@@ -1544,27 +1297,30 @@ int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment)
return 0;
}
-int drmModeAtomicGetCursor(drmModeAtomicReqPtr req)
+drm_public int drmModeAtomicGetCursor(drmModeAtomicReqPtr req)
{
if (!req)
return -EINVAL;
return req->cursor;
}
-void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor)
+drm_public void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor)
{
if (req)
req->cursor = cursor;
}
-int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t value)
+drm_public int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
+ uint32_t object_id,
+ uint32_t property_id,
+ uint64_t value)
{
if (!req)
return -EINVAL;
+ if (object_id == 0 || property_id == 0)
+ return -EINVAL;
+
if (req->cursor >= req->size_items) {
const uint32_t item_size_inc = getpagesize() / sizeof(*req->items);
drmModeAtomicReqItemPtr new;
@@ -1586,7 +1342,7 @@ int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
return req->cursor;
}
-void drmModeAtomicFree(drmModeAtomicReqPtr req)
+drm_public void drmModeAtomicFree(drmModeAtomicReqPtr req)
{
if (!req)
return;
@@ -1609,8 +1365,8 @@ static int sort_req_list(const void *misc, const void *other)
return second->property_id - first->property_id;
}
-int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags,
- void *user_data)
+drm_public int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req,
+ uint32_t flags, void *user_data)
{
drmModeAtomicReqPtr sorted;
struct drm_mode_atomic atomic;
@@ -1714,8 +1470,9 @@ out:
return ret;
}
-int
-drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
+drm_public int
+drmModeCreatePropertyBlob(int fd, const void *data, size_t length,
+ uint32_t *id)
{
struct drm_mode_create_blob create;
int ret;
@@ -1738,7 +1495,7 @@ drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
return 0;
}
-int
+drm_public int
drmModeDestroyPropertyBlob(int fd, uint32_t id)
{
struct drm_mode_destroy_blob destroy;
@@ -1747,3 +1504,93 @@ drmModeDestroyPropertyBlob(int fd, uint32_t id)
destroy.blob_id = id;
return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
}
+
+drm_public int
+drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags,
+ uint32_t *lessee_id)
+{
+ struct drm_mode_create_lease create;
+ int ret;
+
+ memclear(create);
+ create.object_ids = (uintptr_t) objects;
+ create.object_count = num_objects;
+ create.flags = flags;
+
+ ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATE_LEASE, &create);
+ if (ret == 0) {
+ *lessee_id = create.lessee_id;
+ return create.fd;
+ }
+ return -errno;
+}
+
+drm_public drmModeLesseeListPtr
+drmModeListLessees(int fd)
+{
+ struct drm_mode_list_lessees list;
+ uint32_t count;
+ drmModeLesseeListPtr ret;
+
+ memclear(list);
+
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list))
+ return NULL;
+
+ count = list.count_lessees;
+ ret = drmMalloc(sizeof (drmModeLesseeListRes) + count * sizeof (ret->lessees[0]));
+ if (!ret)
+ return NULL;
+
+ list.lessees_ptr = VOID2U64(&ret->lessees[0]);
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list)) {
+ drmFree(ret);
+ return NULL;
+ }
+
+ ret->count = count;
+ return ret;
+}
+
+drm_public drmModeObjectListPtr
+drmModeGetLease(int fd)
+{
+ struct drm_mode_get_lease get;
+ uint32_t count;
+ drmModeObjectListPtr ret;
+
+ memclear(get);
+
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get))
+ return NULL;
+
+ count = get.count_objects;
+ ret = drmMalloc(sizeof (drmModeObjectListRes) + count * sizeof (ret->objects[0]));
+ if (!ret)
+ return NULL;
+
+ get.objects_ptr = VOID2U64(&ret->objects[0]);
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get)) {
+ drmFree(ret);
+ return NULL;
+ }
+
+ ret->count = count;
+ return ret;
+}
+
+drm_public int
+drmModeRevokeLease(int fd, uint32_t lessee_id)
+{
+ struct drm_mode_revoke_lease revoke;
+ int ret;
+
+ memclear(revoke);
+
+ revoke.lessee_id = lessee_id;
+
+ ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_REVOKE_LEASE, &revoke);
+ if (ret == 0)
+ return 0;
+ return -errno;
+}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 9d73be95..3cd27aee 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -369,15 +369,16 @@ extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
uint32_t *buf_id);
/* ...with a specific pixel format */
extern int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
- uint32_t pixel_format, uint32_t bo_handles[4],
- uint32_t pitches[4], uint32_t offsets[4],
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
uint32_t *buf_id, uint32_t flags);
/* ...with format modifiers */
int drmModeAddFB2WithModifiers(int fd, uint32_t width, uint32_t height,
- uint32_t pixel_format, uint32_t bo_handles[4],
- uint32_t pitches[4], uint32_t offsets[4],
- uint64_t modifier[4], uint32_t *buf_id, uint32_t flags);
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
+ const uint64_t modifier[4], uint32_t *buf_id,
+ uint32_t flags);
/**
* Destroies the given framebuffer.
@@ -498,25 +499,6 @@ extern int drmModeObjectSetProperty(int fd, uint32_t object_id,
uint64_t value);
-typedef struct _drmModePropertySet drmModePropertySet, *drmModePropertySetPtr;
-
-extern drmModePropertySetPtr drmModePropertySetAlloc(void);
-
-extern int drmModePropertySetAdd(drmModePropertySetPtr set,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t value);
-extern int drmModePropertySetAddBlob(drmModePropertySetPtr set,
- uint32_t object_id,
- uint32_t property_id,
- uint64_t length,
- void *blob);
-
-extern int drmModePropertySetCommit(int fd, uint32_t flags,
- void *user_data, drmModePropertySetPtr set);
-
-extern void drmModePropertySetFree(drmModePropertySetPtr set);
-
typedef struct _drmModeAtomicReq drmModeAtomicReq, *drmModeAtomicReqPtr;
extern drmModeAtomicReqPtr drmModeAtomicAlloc(void);
@@ -539,6 +521,28 @@ extern int drmModeCreatePropertyBlob(int fd, const void *data, size_t size,
uint32_t *id);
extern int drmModeDestroyPropertyBlob(int fd, uint32_t id);
+/*
+ * DRM mode lease APIs. These create and manage new drm_masters with
+ * access to a subset of the available DRM resources
+ */
+
+extern int drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags, uint32_t *lessee_id);
+
+typedef struct drmModeLesseeList {
+ uint32_t count;
+ uint32_t lessees[0];
+} drmModeLesseeListRes, *drmModeLesseeListPtr;
+
+extern drmModeLesseeListPtr drmModeListLessees(int fd);
+
+typedef struct drmModeObjectList {
+ uint32_t count;
+ uint32_t objects[0];
+} drmModeObjectListRes, *drmModeObjectListPtr;
+
+extern drmModeObjectListPtr drmModeGetLease(int fd);
+
+extern int drmModeRevokeLease(int fd, uint32_t lessee_id);
#if defined(__cplusplus)
}
diff --git a/xf86drmRandom.c b/xf86drmRandom.c
index 81f03014..51e9676f 100644
--- a/xf86drmRandom.c
+++ b/xf86drmRandom.c
@@ -74,12 +74,13 @@
#include <stdio.h>
#include <stdlib.h>
+#include "libdrm_macros.h"
#include "xf86drm.h"
#include "xf86drmRandom.h"
#define RANDOM_MAGIC 0xfeedbeef
-void *drmRandomCreate(unsigned long seed)
+drm_public void *drmRandomCreate(unsigned long seed)
{
RandomState *state;
@@ -109,13 +110,13 @@ void *drmRandomCreate(unsigned long seed)
return state;
}
-int drmRandomDestroy(void *state)
+drm_public int drmRandomDestroy(void *state)
{
drmFree(state);
return 0;
}
-unsigned long drmRandom(void *state)
+drm_public unsigned long drmRandom(void *state)
{
RandomState *s = (RandomState *)state;
unsigned long hi;
@@ -129,7 +130,7 @@ unsigned long drmRandom(void *state)
return s->seed;
}
-double drmRandomDouble(void *state)
+drm_public double drmRandomDouble(void *state)
{
RandomState *s = (RandomState *)state;
diff --git a/xf86drmSL.c b/xf86drmSL.c
index a12fa1d0..3826df97 100644
--- a/xf86drmSL.c
+++ b/xf86drmSL.c
@@ -41,6 +41,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "libdrm_macros.h"
#include "xf86drm.h"
#define SL_LIST_MAGIC 0xfacade00LU
@@ -97,7 +98,7 @@ static int SLRandomLevel(void)
return level;
}
-void *drmSLCreate(void)
+drm_public void *drmSLCreate(void)
{
SkipListPtr list;
int i;
@@ -114,7 +115,7 @@ void *drmSLCreate(void)
return list;
}
-int drmSLDestroy(void *l)
+drm_public int drmSLDestroy(void *l)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
@@ -151,7 +152,7 @@ static SLEntryPtr SLLocate(void *l, unsigned long key, SLEntryPtr *update)
return entry->forward[0];
}
-int drmSLInsert(void *l, unsigned long key, void *value)
+drm_public int drmSLInsert(void *l, unsigned long key, void *value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
@@ -184,7 +185,7 @@ int drmSLInsert(void *l, unsigned long key, void *value)
return 0; /* Added to table */
}
-int drmSLDelete(void *l, unsigned long key)
+drm_public int drmSLDelete(void *l, unsigned long key)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1];
@@ -211,7 +212,7 @@ int drmSLDelete(void *l, unsigned long key)
return 0;
}
-int drmSLLookup(void *l, unsigned long key, void **value)
+drm_public int drmSLLookup(void *l, unsigned long key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1];
@@ -227,9 +228,9 @@ int drmSLLookup(void *l, unsigned long key, void **value)
return -1;
}
-int drmSLLookupNeighbors(void *l, unsigned long key,
- unsigned long *prev_key, void **prev_value,
- unsigned long *next_key, void **next_value)
+drm_public int drmSLLookupNeighbors(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr update[SL_MAX_LEVEL + 1] = {0};
@@ -253,7 +254,7 @@ int drmSLLookupNeighbors(void *l, unsigned long key,
return retcode;
}
-int drmSLNext(void *l, unsigned long *key, void **value)
+drm_public int drmSLNext(void *l, unsigned long *key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;
@@ -272,7 +273,7 @@ int drmSLNext(void *l, unsigned long *key, void **value)
return 0;
}
-int drmSLFirst(void *l, unsigned long *key, void **value)
+drm_public int drmSLFirst(void *l, unsigned long *key, void **value)
{
SkipListPtr list = (SkipListPtr)l;
@@ -283,7 +284,7 @@ int drmSLFirst(void *l, unsigned long *key, void **value)
}
/* Dump internal data structures for debugging. */
-void drmSLDump(void *l)
+drm_public void drmSLDump(void *l)
{
SkipListPtr list = (SkipListPtr)l;
SLEntryPtr entry;