aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore12
-rw-r--r--Android.mk49
-rw-r--r--CleanSpec.mk1
-rw-r--r--Makefile.am46
-rw-r--r--Makefile.sources9
-rw-r--r--RELEASING29
-rw-r--r--amdgpu/Android.mk18
-rw-r--r--amdgpu/Makefile.am47
-rw-r--r--amdgpu/Makefile.sources14
-rwxr-xr-xamdgpu/amdgpu-symbol-check51
-rw-r--r--amdgpu/amdgpu.h1183
-rw-r--r--amdgpu/amdgpu_bo.c713
-rw-r--r--amdgpu/amdgpu_cs.c371
-rw-r--r--amdgpu/amdgpu_device.c305
-rw-r--r--amdgpu/amdgpu_gpu_info.c310
-rw-r--r--amdgpu/amdgpu_internal.h188
-rw-r--r--amdgpu/amdgpu_vamgr.c287
-rw-r--r--amdgpu/libdrm_amdgpu.pc.in10
-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
-rwxr-xr-xautogen.sh16
-rw-r--r--configure.ac214
-rw-r--r--exynos/Makefile.am8
-rwxr-xr-xexynos/exynos-symbol-check40
-rw-r--r--exynos/exynos_drm.c121
-rw-r--r--exynos/exynos_drm.h52
-rw-r--r--exynos/exynos_drmif.h26
-rw-r--r--exynos/exynos_fimg2d.c712
-rw-r--r--exynos/exynos_fimg2d.h (renamed from exynos/fimg2d.h)41
-rw-r--r--exynos/fimg2d_reg.h2
-rw-r--r--exynos/libdrm_exynos.pc.in2
-rw-r--r--freedreno/Android.mk3
-rw-r--r--freedreno/Makefile.am10
-rw-r--r--freedreno/Makefile.sources3
-rwxr-xr-xfreedreno/freedreno-symbol-check54
-rw-r--r--freedreno/freedreno_bo.c84
-rw-r--r--freedreno/freedreno_device.c15
-rw-r--r--freedreno/freedreno_drmif.h4
-rw-r--r--freedreno/freedreno_pipe.c16
-rw-r--r--freedreno/freedreno_priv.h17
-rw-r--r--freedreno/freedreno_ringbuffer.c26
-rw-r--r--freedreno/freedreno_ringbuffer.h2
-rw-r--r--freedreno/kgsl/kgsl_bo.c15
-rw-r--r--freedreno/kgsl/kgsl_device.c4
-rw-r--r--freedreno/kgsl/kgsl_pipe.c25
-rw-r--r--freedreno/kgsl/kgsl_priv.h33
-rw-r--r--freedreno/kgsl/kgsl_ringbuffer.c4
-rw-r--r--freedreno/msm/msm_bo.c12
-rw-r--r--freedreno/msm/msm_device.c4
-rw-r--r--freedreno/msm/msm_pipe.c10
-rw-r--r--freedreno/msm/msm_priv.h32
-rw-r--r--freedreno/msm/msm_ringbuffer.c161
-rw-r--r--include/drm/amdgpu_drm.h645
-rw-r--r--include/drm/drm.h8
-rw-r--r--include/drm/drm_fourcc.h93
-rw-r--r--include/drm/drm_mode.h18
-rw-r--r--include/drm/i915_drm.h105
-rw-r--r--include/drm/virtgpu_drm.h167
-rw-r--r--intel/Android.mk2
-rw-r--r--intel/Makefile.am10
-rwxr-xr-xintel/intel-symbol-check90
-rw-r--r--intel/intel_bufmgr.c82
-rw-r--r--intel/intel_bufmgr.h13
-rw-r--r--intel/intel_bufmgr_fake.c40
-rw-r--r--intel/intel_bufmgr_gem.c978
-rw-r--r--intel/intel_bufmgr_priv.h21
-rw-r--r--intel/intel_chipset.h69
-rw-r--r--intel/intel_decode.c26
-rw-r--r--intel/mm.c29
-rw-r--r--intel/mm.h36
-rw-r--r--intel/test_decode.c9
-rw-r--r--libdrm_macros.h (renamed from libdrm.h)4
-rw-r--r--libkms/Android.mk1
-rw-r--r--libkms/Makefile.am3
-rw-r--r--libkms/api.c3
-rw-r--r--libkms/dumb.c4
-rw-r--r--libkms/exynos.c9
-rw-r--r--libkms/intel.c4
-rw-r--r--libkms/internal.h19
-rwxr-xr-xlibkms/kms-symbol-check25
-rw-r--r--libkms/libkms.h4
-rw-r--r--libkms/linux.c10
-rw-r--r--libkms/nouveau.c4
-rw-r--r--libkms/radeon.c4
-rw-r--r--libkms/vmwgfx.c4
-rw-r--r--man/Makefile.am79
-rw-r--r--nouveau/Android.mk3
-rw-r--r--nouveau/Makefile.am16
-rw-r--r--nouveau/abi16.c182
-rw-r--r--nouveau/bufctx.c16
-rw-r--r--nouveau/libdrm_nouveau.pc.in2
-rwxr-xr-xnouveau/nouveau-symbol-check58
-rw-r--r--nouveau/nouveau.c729
-rw-r--r--nouveau/nouveau.h211
-rw-r--r--nouveau/nvif/cl0080.h45
-rw-r--r--nouveau/nvif/cl9097.h44
-rw-r--r--nouveau/nvif/class.h141
-rw-r--r--nouveau/nvif/if0002.h38
-rw-r--r--nouveau/nvif/if0003.h33
-rw-r--r--nouveau/nvif/ioctl.h132
-rw-r--r--nouveau/nvif/unpack.h28
-rw-r--r--nouveau/private.h18
-rw-r--r--nouveau/pushbuf.c31
-rw-r--r--omap/Makefile.am5
-rwxr-xr-xomap/omap-symbol-check35
-rw-r--r--omap/omap_drm.c43
-rw-r--r--radeon/Android.mk3
-rw-r--r--radeon/Makefile.am4
-rw-r--r--radeon/Makefile.sources8
-rw-r--r--radeon/r600_pci_ids.h2
-rwxr-xr-xradeon/radeon-symbol-check61
-rw-r--r--radeon/radeon_bo.c30
-rw-r--r--radeon/radeon_bo_gem.c41
-rw-r--r--radeon/radeon_bo_int.h2
-rw-r--r--radeon/radeon_cs.c26
-rw-r--r--radeon/radeon_cs_gem.c31
-rw-r--r--radeon/radeon_cs_int.h2
-rw-r--r--radeon/radeon_cs_space.c10
-rw-r--r--radeon/radeon_surface.c31
-rw-r--r--tegra/Makefile.am4
-rw-r--r--tegra/private.h2
-rwxr-xr-xtegra/tegra-symbol-check30
-rw-r--r--tegra/tegra.c15
-rw-r--r--tests/Android.mk1
-rw-r--r--tests/Makefile.am67
-rw-r--r--tests/amdgpu/Makefile.am29
-rw-r--r--tests/amdgpu/amdgpu_test.c243
-rw-r--r--tests/amdgpu/amdgpu_test.h236
-rw-r--r--tests/amdgpu/basic_tests.c846
-rw-r--r--tests/amdgpu/bo_tests.c186
-rw-r--r--tests/amdgpu/cs_tests.c392
-rw-r--r--tests/amdgpu/frame.h1949
-rw-r--r--tests/amdgpu/uvd_messages.h813
-rw-r--r--tests/amdgpu/vce_ib.h318
-rw-r--r--tests/amdgpu/vce_tests.c493
-rw-r--r--tests/auth.c1
-rw-r--r--tests/dristat.c7
-rw-r--r--tests/drmdevice.c112
-rw-r--r--tests/drmsl.c172
-rw-r--r--tests/drmstat.c22
-rw-r--r--tests/exynos/Makefile.am27
-rw-r--r--tests/exynos/exynos_fimg2d_event.c326
-rw-r--r--tests/exynos/exynos_fimg2d_perf.c327
-rw-r--r--tests/exynos/exynos_fimg2d_test.c419
-rw-r--r--tests/gem_basic.c102
-rw-r--r--tests/gem_flink.c137
-rw-r--r--tests/gem_mmap.c136
-rw-r--r--tests/gem_readwrite.c139
-rw-r--r--tests/getclient.c1
-rw-r--r--tests/getstats.c3
-rw-r--r--tests/hash.c217
-rw-r--r--tests/kms/Makefile.am36
-rw-r--r--tests/kms/kms-steal-crtc.c161
-rw-r--r--tests/kms/kms-universal-planes.c358
-rw-r--r--tests/kms/libkms-test-crtc.c47
-rw-r--r--tests/kms/libkms-test-device.c218
-rw-r--r--tests/kms/libkms-test-framebuffer.c157
-rw-r--r--tests/kms/libkms-test-plane.c139
-rw-r--r--tests/kms/libkms-test-screen.c92
-rw-r--r--tests/kms/libkms-test.h120
-rw-r--r--tests/kmstest/Makefile.am1
-rw-r--r--tests/kmstest/main.c8
-rw-r--r--tests/lock.c1
-rw-r--r--tests/modeprint/Makefile.am2
-rw-r--r--tests/modeprint/modeprint.c42
-rw-r--r--tests/modetest/Android.mk1
-rw-r--r--tests/modetest/Makefile.am8
-rw-r--r--tests/modetest/buffers.c967
-rw-r--r--tests/modetest/buffers.h12
-rw-r--r--tests/modetest/cursor.c14
-rw-r--r--tests/modetest/modetest.c315
-rw-r--r--tests/name_from_fd.c6
-rw-r--r--tests/nouveau/.gitignore1
-rw-r--r--tests/nouveau/Makefile.am16
-rw-r--r--tests/nouveau/threaded.c156
-rw-r--r--tests/proptest/Android.mk13
-rw-r--r--tests/proptest/Makefile.am16
-rw-r--r--tests/proptest/Makefile.sources2
-rw-r--r--tests/proptest/proptest.c104
-rw-r--r--tests/radeon/Makefile.am2
-rw-r--r--tests/radeon/list.h137
-rw-r--r--tests/radeon/radeon_ttm.c4
-rw-r--r--tests/radeon/rbo.h2
-rw-r--r--tests/random.c120
-rw-r--r--tests/setversion.c1
-rw-r--r--tests/tegra/Makefile.am2
-rw-r--r--tests/updatedraw.c3
-rw-r--r--tests/util/Android.mk39
-rw-r--r--tests/util/Makefile.am13
-rw-r--r--tests/util/Makefile.sources8
-rw-r--r--tests/util/common.h33
-rw-r--r--tests/util/format.c120
-rw-r--r--tests/util/format.h65
-rw-r--r--tests/util/kms.c177
-rw-r--r--tests/util/kms.h35
-rw-r--r--tests/util/pattern.c870
-rw-r--r--tests/util/pattern.h39
-rw-r--r--tests/vbltest/Makefile.am6
-rw-r--r--tests/vbltest/vbltest.c57
-rw-r--r--util_double_list.h (renamed from freedreno/list.h)0
-rw-r--r--util_math.h34
-rw-r--r--xf86atomic.h19
-rw-r--r--xf86drm.c906
-rw-r--r--xf86drm.h64
-rw-r--r--xf86drmHash.c205
-rw-r--r--xf86drmHash.h47
-rw-r--r--xf86drmMode.c429
-rw-r--r--xf86drmMode.h46
-rw-r--r--xf86drmRandom.c85
-rw-r--r--xf86drmRandom.h35
-rw-r--r--xf86drmSL.c179
213 files changed, 20960 insertions, 4526 deletions
diff --git a/.gitignore b/.gitignore
index 3596a4a8..c1e87c50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,7 @@ libdrm_radeon.pc
55libdrm_omap.pc 55libdrm_omap.pc
56libdrm_exynos.pc 56libdrm_exynos.pc
57libdrm_freedreno.pc 57libdrm_freedreno.pc
58libdrm_amdgpu.pc
58libkms.pc 59libkms.pc
59libtool 60libtool
60ltmain.sh 61ltmain.sh
@@ -73,17 +74,18 @@ stamp-h1
73tdfx.kld 74tdfx.kld
74via.kld 75via.kld
75tests/auth 76tests/auth
77tests/amdgpu/amdgpu_test
76tests/dristat 78tests/dristat
79tests/drmdevice
80tests/drmsl
77tests/drmstat 81tests/drmstat
78tests/getclient 82tests/getclient
79tests/getstats 83tests/getstats
80tests/getversion 84tests/getversion
85tests/hash
81tests/lock 86tests/lock
82tests/gem_basic
83tests/gem_flink
84tests/gem_mmap
85tests/gem_readwrite
86tests/openclose 87tests/openclose
88tests/random
87tests/setversion 89tests/setversion
88tests/updatedraw 90tests/updatedraw
89tests/modeprint/modeprint 91tests/modeprint/modeprint
@@ -93,5 +95,7 @@ tests/proptest/proptest
93tests/kmstest/kmstest 95tests/kmstest/kmstest
94tests/vbltest/vbltest 96tests/vbltest/vbltest
95tests/radeon/radeon_ttm 97tests/radeon/radeon_ttm
98tests/exynos/exynos_fimg2d_event
99tests/exynos/exynos_fimg2d_perf
96tests/exynos/exynos_fimg2d_test 100tests/exynos/exynos_fimg2d_test
97man/*.3 101man/*.3
diff --git a/Android.mk b/Android.mk
index 35ea3671..76df4f19 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,35 +26,44 @@ LOCAL_PATH := $(call my-dir)
26# Import variables LIBDRM_{,H_,INCLUDE_H_,INCLUDE_VMWGFX_H_}FILES 26# Import variables LIBDRM_{,H_,INCLUDE_H_,INCLUDE_VMWGFX_H_}FILES
27include $(LOCAL_PATH)/Makefile.sources 27include $(LOCAL_PATH)/Makefile.sources
28 28
29common_CFLAGS := -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 29common_CFLAGS := \
30 -DHAVE_VISIBILITY=1 \
31 -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1
30 32
31# Static library for the device (recovery) 33# Static library for the device (recovery)
32include $(CLEAR_VARS) 34include $(CLEAR_VARS)
33LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_FILES)) 35
34LOCAL_EXPORT_C_INCLUDE_DIRS += $(LOCAL_PATH) $(LOCAL_PATH)/include/drm
35LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/drm
36LOCAL_CFLAGS := $(common_CFLAGS)
37LOCAL_MODULE := libdrm 36LOCAL_MODULE := libdrm
37
38LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_FILES))
39LOCAL_EXPORT_C_INCLUDE_DIRS := \
40 $(LOCAL_PATH) \
41 $(LOCAL_PATH)/include/drm
42
43LOCAL_C_INCLUDES := \
44 $(LOCAL_PATH)/include/drm
45
46LOCAL_CFLAGS := \
47 $(common_CFLAGS)
48
38include $(BUILD_STATIC_LIBRARY) 49include $(BUILD_STATIC_LIBRARY)
39 50
40# Dynamic library for the device 51# Dynamic library for the device
41include $(CLEAR_VARS) 52include $(CLEAR_VARS)
42LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_FILES))
43LOCAL_EXPORT_C_INCLUDE_DIRS += $(LOCAL_PATH) $(LOCAL_PATH)/include/drm
44LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/drm
45LOCAL_CFLAGS := $(common_CFLAGS)
46 53
47LOCAL_MODULE := libdrm 54LOCAL_MODULE := libdrm
55
56LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_FILES))
57LOCAL_EXPORT_C_INCLUDE_DIRS := \
58 $(LOCAL_PATH) \
59 $(LOCAL_PATH)/include/drm
60
61LOCAL_C_INCLUDES := \
62 $(LOCAL_PATH)/include/drm
63
64LOCAL_CFLAGS := \
65 $(common_CFLAGS)
66
48include $(BUILD_SHARED_LIBRARY) 67include $(BUILD_SHARED_LIBRARY)
49 68
50SUBDIRS := \ 69include $(call all-makefiles-under,$(LOCAL_PATH))
51 nouveau \
52 radeon \
53 rockchip \
54 tegra \
55 libkms \
56 tests/modetest \
57 tests/planetest
58
59mkfiles := $(patsubst %,$(LOCAL_PATH)/%/Android.mk,$(SUBDIRS))
60include $(mkfiles)
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 8e23cd25..28a11db4 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -1,3 +1,4 @@
1$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/libdrm) 1$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/libdrm)
2$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/freedreno) 2$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/freedreno)
3$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libdrm_*intermediates) 3$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libdrm_*intermediates)
4$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libdrm_*intermediates)
diff --git a/Makefile.am b/Makefile.am
index c4cd3f6e..11ed1028 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,6 +22,24 @@ include Makefile.sources
22 22
23ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} 23ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
24 24
25AM_DISTCHECK_CONFIGURE_FLAGS = \
26 --enable-udev \
27 --enable-libkms \
28 --enable-intel \
29 --enable-radeon \
30 --enable-amdgpu \
31 --enable-nouveau \
32 --enable-vmwgfx \
33 --enable-omap-experimental-api \
34 --enable-exynos-experimental-api \
35 --enable-freedreno \
36 --enable-freedreno-kgsl\
37 --enable-tegra-experimental-api \
38 --enable-install-test-programs \
39 --enable-cairo-tests \
40 --enable-manpages \
41 --enable-valgrind
42
25pkgconfigdir = @pkgconfigdir@ 43pkgconfigdir = @pkgconfigdir@
26pkgconfig_DATA = libdrm.pc 44pkgconfig_DATA = libdrm.pc
27 45
@@ -41,6 +59,10 @@ if HAVE_RADEON
41RADEON_SUBDIR = radeon 59RADEON_SUBDIR = radeon
42endif 60endif
43 61
62if HAVE_AMDGPU
63AMDGPU_SUBDIR = amdgpu
64endif
65
44if HAVE_OMAP 66if HAVE_OMAP
45OMAP_SUBDIR = omap 67OMAP_SUBDIR = omap
46endif 68endif
@@ -57,19 +79,39 @@ if HAVE_TEGRA
57TEGRA_SUBDIR = tegra 79TEGRA_SUBDIR = tegra
58endif 80endif
59 81
82if BUILD_MANPAGES
83if HAVE_MANPAGES_STYLESHEET
84MAN_SUBDIR = man
85endif
86endif
87
60if HAVE_ROCKCHIP 88if HAVE_ROCKCHIP
61ROCKCHIP_SUBDIR = rockchip 89ROCKCHIP_SUBDIR = rockchip
62endif 90endif
63 91
64SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) $(FREEDRENO_SUBDIR) $(TEGRA_SUBDIR) $(ROCKCHIP_SUBDIR) tests man 92SUBDIRS = \
93 . \
94 $(LIBKMS_SUBDIR) \
95 $(INTEL_SUBDIR) \
96 $(NOUVEAU_SUBDIR) \
97 $(RADEON_SUBDIR) \
98 $(AMDGPU_SUBDIR) \
99 $(OMAP_SUBDIR) \
100 $(EXYNOS_SUBDIR) \
101 $(FREEDRENO_SUBDIR) \
102 $(TEGRA_SUBDIR) \
103 tests \
104 $(MAN_SUBDIR) \
105 $(ROCKCHIP_SUBDIR)
65 106
66libdrm_la_LTLIBRARIES = libdrm.la 107libdrm_la_LTLIBRARIES = libdrm.la
67libdrm_ladir = $(libdir) 108libdrm_ladir = $(libdir)
68libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined 109libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined
69libdrm_la_LIBADD = @CLOCK_LIB@ 110libdrm_la_LIBADD = @CLOCK_LIB@ -lm
70 111
71libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm 112libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm
72AM_CFLAGS = \ 113AM_CFLAGS = \
114 $(WARN_CFLAGS) \
73 $(VALGRIND_CFLAGS) 115 $(VALGRIND_CFLAGS)
74 116
75libdrm_la_SOURCES = $(LIBDRM_FILES) 117libdrm_la_SOURCES = $(LIBDRM_FILES)
diff --git a/Makefile.sources b/Makefile.sources
index 566f7b55..a77f48de 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -1,12 +1,16 @@
1LIBDRM_FILES := \ 1LIBDRM_FILES := \
2 xf86drm.c \ 2 xf86drm.c \
3 xf86drmHash.c \ 3 xf86drmHash.c \
4 xf86drmHash.h \
4 xf86drmRandom.c \ 5 xf86drmRandom.c \
6 xf86drmRandom.h \
5 xf86drmSL.c \ 7 xf86drmSL.c \
6 xf86drmMode.c \ 8 xf86drmMode.c \
7 xf86atomic.h \ 9 xf86atomic.h \
8 libdrm.h \ 10 libdrm_macros.h \
9 libdrm_lists.h 11 libdrm_lists.h \
12 util_double_list.h \
13 util_math.h
10 14
11LIBDRM_H_FILES := \ 15LIBDRM_H_FILES := \
12 xf86drm.h \ 16 xf86drm.h \
@@ -24,6 +28,7 @@ LIBDRM_INCLUDE_H_FILES := \
24 include/drm/qxl_drm.h \ 28 include/drm/qxl_drm.h \
25 include/drm/r128_drm.h \ 29 include/drm/r128_drm.h \
26 include/drm/radeon_drm.h \ 30 include/drm/radeon_drm.h \
31 include/drm/amdgpu_drm.h \
27 include/drm/savage_drm.h \ 32 include/drm/savage_drm.h \
28 include/drm/sis_drm.h \ 33 include/drm/sis_drm.h \
29 include/drm/tegra_drm.h \ 34 include/drm/tegra_drm.h \
diff --git a/RELEASING b/RELEASING
index 3f07146d..62c5be9f 100644
--- a/RELEASING
+++ b/RELEASING
@@ -13,20 +13,19 @@ Follow these steps to release a new version of libdrm:
13 modifications. You're probably in a good state if both "git diff 13 modifications. You're probably in a good state if both "git diff
14 HEAD" and "git log master..origin/master" give no output. 14 HEAD" and "git log master..origin/master" give no output.
15 15
16 3) Bump the version number in configure.ac. We seem to have settled 16 2) Bump the version number in configure.ac. We seem to have settled
17 for 2.4.x as the versioning scheme for libdrm, so just bump the 17 for 2.4.x as the versioning scheme for libdrm, so just bump the
18 micro version. 18 micro version.
19 19
20 4) Run autoconf and then re-run ./configure so the build system 20 3) Run autoconf and then re-run ./configure so the build system
21 picks up the new version number. 21 picks up the new version number.
22 22
23 5) Verify that the code passes "make distcheck". libdrm is tricky 23 4) (optional step, release.sh will make distcheck for you, but it can be
24 to distcheck since the test suite will need to become drm master. 24 heart warming to verify that make distcheck passes)
25 This means that you need to run it outside X, that is, in text
26 mode (KMS or no KMS doesn't matter).
27 25
28 Running "make distcheck" should result in no warnings or errors 26 Verify that the code passes "make distcheck". Running "make
29 and end with a message of the form: 27 distcheck" should result in no warnings or errors and end with a
28 message of the form:
30 29
31 ============================================= 30 =============================================
32 libdrm-X.Y.Z archives ready for distribution: 31 libdrm-X.Y.Z archives ready for distribution:
@@ -37,26 +36,26 @@ Follow these steps to release a new version of libdrm:
37 Make sure that the version number reported by distcheck and in 36 Make sure that the version number reported by distcheck and in
38 the tarball names matches the number you bumped to in configure.ac. 37 the tarball names matches the number you bumped to in configure.ac.
39 38
40 6) Commit the configure.ac change and make an annotated tag for that 39 5) Commit the configure.ac change and make an annotated tag for that
41 commit with the version number of the release as the name and a 40 commit with the version number of the release as the name and a
42 message of "libdrm X.Y.Z". For example, for the 2.4.16 release 41 message of "libdrm X.Y.Z". For example, for the 2.4.16 release
43 the command is: 42 the command is:
44 43
45 git tag -a 2.4.16 -m "libdrm 2.4.16" 44 git tag -a 2.4.16 -m "libdrm 2.4.16"
46 45
47 7) Push the commit and tag by saying 46 6) Push the commit and tag by saying
48 47
49 git push --tags origin master 48 git push --tags origin master
50 49
51 assuming the remote for the upstream libdrm repo is called origin. 50 assuming the remote for the upstream libdrm repo is called origin.
52 51
53 6) Use the release.sh script from the xorg/util/modular repo to 52 7) Use the release.sh script from the xorg/util/modular repo to
54 upload the tarballs to the freedesktop.org download area and 53 upload the tarballs to the freedesktop.org download area and
55 create an annouce email template. The script takes three 54 create an announce email template. The script takes one argument:
56 arguments: a "section", the previous tag and the new tag we just 55 the path to the libdrm checkout. So, if a checkout of modular is
57 created. For 2.4.16 again, the command is: 56 at the same level than the libdrm repo:
58 57
59 ../modular/release.sh libdrm 2.4.15 2.4.16 58 ./modular/release.sh libdrm
60 59
61 This copies the two tarballs to freedesktop.org and creates 60 This copies the two tarballs to freedesktop.org and creates
62 libdrm-2.4.16.announce which has a detailed summary of the 61 libdrm-2.4.16.announce which has a detailed summary of the
diff --git a/amdgpu/Android.mk b/amdgpu/Android.mk
new file mode 100644
index 00000000..469df1b2
--- /dev/null
+++ b/amdgpu/Android.mk
@@ -0,0 +1,18 @@
1LOCAL_PATH := $(call my-dir)
2include $(CLEAR_VARS)
3
4# Import variables LIBDRM_AMDGPU_FILES, LIBDRM_AMDGPU_H_FILES
5include $(LOCAL_PATH)/Makefile.sources
6
7LOCAL_MODULE := libdrm_amdgpu
8LOCAL_MODULE_TAGS := optional
9
10LOCAL_SHARED_LIBRARIES := libdrm
11
12LOCAL_SRC_FILES := $(LIBDRM_AMDGPU_FILES)
13LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
14
15LOCAL_CFLAGS := \
16 -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1
17
18include $(BUILD_SHARED_LIBRARY)
diff --git a/amdgpu/Makefile.am b/amdgpu/Makefile.am
new file mode 100644
index 00000000..cf7bc1ba
--- /dev/null
+++ b/amdgpu/Makefile.am
@@ -0,0 +1,47 @@
1# Copyright © 2008 Jérôme Glisse
2#
3# Permission is hereby granted, free of charge, to any person obtaining a
4# copy of this software and associated documentation files (the "Software"),
5# to deal in the Software without restriction, including without limitation
6# the rights to use, copy, modify, merge, publish, distribute, sublicense,
7# and/or sell copies of the Software, and to permit persons to whom the
8# Software is furnished to do so, subject to the following conditions:
9#
10# The above copyright notice and this permission notice (including the next
11# paragraph) shall be included in all copies or substantial portions of the
12# Software.
13#
14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20# IN THE SOFTWARE.
21#
22# Authors:
23# Jérôme Glisse <glisse@freedesktop.org>
24
25include Makefile.sources
26
27AM_CFLAGS = \
28 $(WARN_CFLAGS) \
29 -I$(top_srcdir) \
30 $(PTHREADSTUBS_CFLAGS) \
31 -I$(top_srcdir)/include/drm
32
33libdrm_amdgpu_la_LTLIBRARIES = libdrm_amdgpu.la
34libdrm_amdgpu_ladir = $(libdir)
35libdrm_amdgpu_la_LDFLAGS = -version-number 1:0:0 -no-undefined
36libdrm_amdgpu_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
37
38libdrm_amdgpu_la_SOURCES = $(LIBDRM_AMDGPU_FILES)
39
40libdrm_amdgpuincludedir = ${includedir}/libdrm
41libdrm_amdgpuinclude_HEADERS = $(LIBDRM_AMDGPU_H_FILES)
42
43pkgconfigdir = @pkgconfigdir@
44pkgconfig_DATA = libdrm_amdgpu.pc
45
46TESTS = amdgpu-symbol-check
47EXTRA_DIST = $(TESTS)
diff --git a/amdgpu/Makefile.sources b/amdgpu/Makefile.sources
new file mode 100644
index 00000000..0c0b9a93
--- /dev/null
+++ b/amdgpu/Makefile.sources
@@ -0,0 +1,14 @@
1LIBDRM_AMDGPU_FILES := \
2 amdgpu_bo.c \
3 amdgpu_cs.c \
4 amdgpu_device.c \
5 amdgpu_gpu_info.c \
6 amdgpu_internal.h \
7 amdgpu_vamgr.c \
8 util_hash.c \
9 util_hash.h \
10 util_hash_table.c \
11 util_hash_table.h
12
13LIBDRM_AMDGPU_H_FILES := \
14 amdgpu.h
diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
new file mode 100755
index 00000000..9a0b36cb
--- /dev/null
+++ b/amdgpu/amdgpu-symbol-check
@@ -0,0 +1,51 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.am/libdrm_amdgpuinclude_HEADERS
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_amdgpu.so} | awk '{print $3}' | while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13amdgpu_bo_alloc
14amdgpu_bo_cpu_map
15amdgpu_bo_cpu_unmap
16amdgpu_bo_export
17amdgpu_bo_free
18amdgpu_bo_import
19amdgpu_bo_list_create
20amdgpu_bo_list_destroy
21amdgpu_bo_list_update
22amdgpu_bo_query_info
23amdgpu_bo_set_metadata
24amdgpu_bo_va_op
25amdgpu_bo_wait_for_idle
26amdgpu_create_bo_from_user_mem
27amdgpu_cs_ctx_create
28amdgpu_cs_ctx_free
29amdgpu_cs_query_fence_status
30amdgpu_cs_query_reset_state
31amdgpu_cs_submit
32amdgpu_device_deinitialize
33amdgpu_device_initialize
34amdgpu_query_buffer_size_alignment
35amdgpu_query_crtc_from_id
36amdgpu_query_firmware_version
37amdgpu_query_gds_info
38amdgpu_query_gpu_info
39amdgpu_query_heap_info
40amdgpu_query_hw_ip_count
41amdgpu_query_hw_ip_info
42amdgpu_query_info
43amdgpu_read_mm_registers
44amdgpu_va_range_alloc
45amdgpu_va_range_free
46amdgpu_va_range_query
47EOF
48done)
49
50test ! -n "$FUNCS" || echo $FUNCS
51test ! -n "$FUNCS"
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
new file mode 100644
index 00000000..e44d802b
--- /dev/null
+++ b/amdgpu/amdgpu.h
@@ -0,0 +1,1183 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24/**
25 * \file amdgpu.h
26 *
27 * Declare public libdrm_amdgpu API
28 *
29 * This file define API exposed by libdrm_amdgpu library.
30 * User wanted to use libdrm_amdgpu functionality must include
31 * this file.
32 *
33 */
34#ifndef _AMDGPU_H_
35#define _AMDGPU_H_
36
37#include <stdint.h>
38#include <stdbool.h>
39
40struct drm_amdgpu_info_hw_ip;
41
42/*--------------------------------------------------------------------------*/
43/* --------------------------- Defines ------------------------------------ */
44/*--------------------------------------------------------------------------*/
45
46/**
47 * Define max. number of Command Buffers (IB) which could be sent to the single
48 * hardware IP to accommodate CE/DE requirements
49 *
50 * \sa amdgpu_cs_ib_info
51*/
52#define AMDGPU_CS_MAX_IBS_PER_SUBMIT 4
53
54/**
55 * Special timeout value meaning that the timeout is infinite.
56 */
57#define AMDGPU_TIMEOUT_INFINITE 0xffffffffffffffffull
58
59/**
60 * Used in amdgpu_cs_query_fence_status(), meaning that the given timeout
61 * is absolute.
62 */
63#define AMDGPU_QUERY_FENCE_TIMEOUT_IS_ABSOLUTE (1 << 0)
64
65/*--------------------------------------------------------------------------*/
66/* ----------------------------- Enums ------------------------------------ */
67/*--------------------------------------------------------------------------*/
68
69/**
70 * Enum describing possible handle types
71 *
72 * \sa amdgpu_bo_import, amdgpu_bo_export
73 *
74*/
75enum amdgpu_bo_handle_type {
76 /** GEM flink name (needs DRM authentication, used by DRI2) */
77 amdgpu_bo_handle_type_gem_flink_name = 0,
78
79 /** KMS handle which is used by all driver ioctls */
80 amdgpu_bo_handle_type_kms = 1,
81
82 /** DMA-buf fd handle */
83 amdgpu_bo_handle_type_dma_buf_fd = 2
84};
85
86/** Define known types of GPU VM VA ranges */
87enum amdgpu_gpu_va_range
88{
89 /** Allocate from "normal"/general range */
90 amdgpu_gpu_va_range_general = 0
91};
92
93/*--------------------------------------------------------------------------*/
94/* -------------------------- Datatypes ----------------------------------- */
95/*--------------------------------------------------------------------------*/
96
97/**
98 * Define opaque pointer to context associated with fd.
99 * This context will be returned as the result of
100 * "initialize" function and should be pass as the first
101 * parameter to any API call
102 */
103typedef struct amdgpu_device *amdgpu_device_handle;
104
105/**
106 * Define GPU Context type as pointer to opaque structure
107 * Example of GPU Context is the "rendering" context associated
108 * with OpenGL context (glCreateContext)
109 */
110typedef struct amdgpu_context *amdgpu_context_handle;
111
112/**
113 * Define handle for amdgpu resources: buffer, GDS, etc.
114 */
115typedef struct amdgpu_bo *amdgpu_bo_handle;
116
117/**
118 * Define handle for list of BOs
119 */
120typedef struct amdgpu_bo_list *amdgpu_bo_list_handle;
121
122/**
123 * Define handle to be used to work with VA allocated ranges
124 */
125typedef struct amdgpu_va *amdgpu_va_handle;
126
127/*--------------------------------------------------------------------------*/
128/* -------------------------- Structures ---------------------------------- */
129/*--------------------------------------------------------------------------*/
130
131/**
132 * Structure describing memory allocation request
133 *
134 * \sa amdgpu_bo_alloc()
135 *
136*/
137struct amdgpu_bo_alloc_request {
138 /** Allocation request. It must be aligned correctly. */
139 uint64_t alloc_size;
140
141 /**
142 * It may be required to have some specific alignment requirements
143 * for physical back-up storage (e.g. for displayable surface).
144 * If 0 there is no special alignment requirement
145 */
146 uint64_t phys_alignment;
147
148 /**
149 * UMD should specify where to allocate memory and how it
150 * will be accessed by the CPU.
151 */
152 uint32_t preferred_heap;
153
154 /** Additional flags passed on allocation */
155 uint64_t flags;
156};
157
158/**
159 * Special UMD specific information associated with buffer.
160 *
161 * It may be need to pass some buffer charactersitic as part
162 * of buffer sharing. Such information are defined UMD and
163 * opaque for libdrm_amdgpu as well for kernel driver.
164 *
165 * \sa amdgpu_bo_set_metadata(), amdgpu_bo_query_info,
166 * amdgpu_bo_import(), amdgpu_bo_export
167 *
168*/
169struct amdgpu_bo_metadata {
170 /** Special flag associated with surface */
171 uint64_t flags;
172
173 /**
174 * ASIC-specific tiling information (also used by DCE).
175 * The encoding is defined by the AMDGPU_TILING_* definitions.
176 */
177 uint64_t tiling_info;
178
179 /** Size of metadata associated with the buffer, in bytes. */
180 uint32_t size_metadata;
181
182 /** UMD specific metadata. Opaque for kernel */
183 uint32_t umd_metadata[64];
184};
185
186/**
187 * Structure describing allocated buffer. Client may need
188 * to query such information as part of 'sharing' buffers mechanism
189 *
190 * \sa amdgpu_bo_set_metadata(), amdgpu_bo_query_info(),
191 * amdgpu_bo_import(), amdgpu_bo_export()
192*/
193struct amdgpu_bo_info {
194 /** Allocated memory size */
195 uint64_t alloc_size;
196
197 /**
198 * It may be required to have some specific alignment requirements
199 * for physical back-up storage.
200 */
201 uint64_t phys_alignment;
202
203 /** Heap where to allocate memory. */
204 uint32_t preferred_heap;
205
206 /** Additional allocation flags. */
207 uint64_t alloc_flags;
208
209 /** Metadata associated with buffer if any. */
210 struct amdgpu_bo_metadata metadata;
211};
212
213/**
214 * Structure with information about "imported" buffer
215 *
216 * \sa amdgpu_bo_import()
217 *
218 */
219struct amdgpu_bo_import_result {
220 /** Handle of memory/buffer to use */
221 amdgpu_bo_handle buf_handle;
222
223 /** Buffer size */
224 uint64_t alloc_size;
225};
226
227/**
228 *
229 * Structure to describe GDS partitioning information.
230 * \note OA and GWS resources are asscoiated with GDS partition
231 *
232 * \sa amdgpu_gpu_resource_query_gds_info
233 *
234*/
235struct amdgpu_gds_resource_info {
236 uint32_t gds_gfx_partition_size;
237 uint32_t compute_partition_size;
238 uint32_t gds_total_size;
239 uint32_t gws_per_gfx_partition;
240 uint32_t gws_per_compute_partition;
241 uint32_t oa_per_gfx_partition;
242 uint32_t oa_per_compute_partition;
243};
244
245/**
246 * Structure describing CS fence
247 *
248 * \sa amdgpu_cs_query_fence_status(), amdgpu_cs_request, amdgpu_cs_submit()
249 *
250*/
251struct amdgpu_cs_fence {
252
253 /** In which context IB was sent to execution */
254 amdgpu_context_handle context;
255
256 /** To which HW IP type the fence belongs */
257 uint32_t ip_type;
258
259 /** IP instance index if there are several IPs of the same type. */
260 uint32_t ip_instance;
261
262 /** Ring index of the HW IP */
263 uint32_t ring;
264
265 /** Specify fence for which we need to check submission status.*/
266 uint64_t fence;
267};
268
269/**
270 * Structure describing IB
271 *
272 * \sa amdgpu_cs_request, amdgpu_cs_submit()
273 *
274*/
275struct amdgpu_cs_ib_info {
276 /** Special flags */
277 uint64_t flags;
278
279 /** Virtual MC address of the command buffer */
280 uint64_t ib_mc_address;
281
282 /**
283 * Size of Command Buffer to be submitted.
284 * - The size is in units of dwords (4 bytes).
285 * - Could be 0
286 */
287 uint32_t size;
288};
289
290/**
291 * Structure describing fence information
292 *
293 * \sa amdgpu_cs_request, amdgpu_cs_query_fence,
294 * amdgpu_cs_submit(), amdgpu_cs_query_fence_status()
295*/
296struct amdgpu_cs_fence_info {
297 /** buffer object for the fence */
298 amdgpu_bo_handle handle;
299
300 /** fence offset in the unit of sizeof(uint64_t) */
301 uint64_t offset;
302};
303
304/**
305 * Structure describing submission request
306 *
307 * \note We could have several IBs as packet. e.g. CE, CE, DE case for gfx
308 *
309 * \sa amdgpu_cs_submit()
310*/
311struct amdgpu_cs_request {
312 /** Specify flags with additional information */
313 uint64_t flags;
314
315 /** Specify HW IP block type to which to send the IB. */
316 unsigned ip_type;
317
318 /** IP instance index if there are several IPs of the same type. */
319 unsigned ip_instance;
320
321 /**
322 * Specify ring index of the IP. We could have several rings
323 * in the same IP. E.g. 0 for SDMA0 and 1 for SDMA1.
324 */
325 uint32_t ring;
326
327 /**
328 * List handle with resources used by this request.
329 */
330 amdgpu_bo_list_handle resources;
331
332 /**
333 * Number of dependencies this Command submission needs to
334 * wait for before starting execution.
335 */
336 uint32_t number_of_dependencies;
337
338 /**
339 * Array of dependencies which need to be met before
340 * execution can start.
341 */
342 struct amdgpu_cs_fence *dependencies;
343
344 /** Number of IBs to submit in the field ibs. */
345 uint32_t number_of_ibs;
346
347 /**
348 * IBs to submit. Those IBs will be submit together as single entity
349 */
350 struct amdgpu_cs_ib_info *ibs;
351
352 /**
353 * The returned sequence number for the command submission
354 */
355 uint64_t seq_no;
356
357 /**
358 * The fence information
359 */
360 struct amdgpu_cs_fence_info fence_info;
361};
362
363/**
364 * Structure which provide information about GPU VM MC Address space
365 * alignments requirements
366 *
367 * \sa amdgpu_query_buffer_size_alignment
368 */
369struct amdgpu_buffer_size_alignments {
370 /** Size alignment requirement for allocation in
371 * local memory */
372 uint64_t size_local;
373
374 /**
375 * Size alignment requirement for allocation in remote memory
376 */
377 uint64_t size_remote;
378};
379
380/**
381 * Structure which provide information about heap
382 *
383 * \sa amdgpu_query_heap_info()
384 *
385 */
386struct amdgpu_heap_info {
387 /** Theoretical max. available memory in the given heap */
388 uint64_t heap_size;
389
390 /**
391 * Number of bytes allocated in the heap. This includes all processes
392 * and private allocations in the kernel. It changes when new buffers
393 * are allocated, freed, and moved. It cannot be larger than
394 * heap_size.
395 */
396 uint64_t heap_usage;
397
398 /**
399 * Theoretical possible max. size of buffer which
400 * could be allocated in the given heap
401 */
402 uint64_t max_allocation;
403};
404
405/**
406 * Describe GPU h/w info needed for UMD correct initialization
407 *
408 * \sa amdgpu_query_gpu_info()
409*/
410struct amdgpu_gpu_info {
411 /** Asic id */
412 uint32_t asic_id;
413 /** Chip revision */
414 uint32_t chip_rev;
415 /** Chip external revision */
416 uint32_t chip_external_rev;
417 /** Family ID */
418 uint32_t family_id;
419 /** Special flags */
420 uint64_t ids_flags;
421 /** max engine clock*/
422 uint64_t max_engine_clk;
423 /** max memory clock */
424 uint64_t max_memory_clk;
425 /** number of shader engines */
426 uint32_t num_shader_engines;
427 /** number of shader arrays per engine */
428 uint32_t num_shader_arrays_per_engine;
429 /** Number of available good shader pipes */
430 uint32_t avail_quad_shader_pipes;
431 /** Max. number of shader pipes.(including good and bad pipes */
432 uint32_t max_quad_shader_pipes;
433 /** Number of parameter cache entries per shader quad pipe */
434 uint32_t cache_entries_per_quad_pipe;
435 /** Number of available graphics context */
436 uint32_t num_hw_gfx_contexts;
437 /** Number of render backend pipes */
438 uint32_t rb_pipes;
439 /** Enabled render backend pipe mask */
440 uint32_t enabled_rb_pipes_mask;
441 /** Frequency of GPU Counter */
442 uint32_t gpu_counter_freq;
443 /** CC_RB_BACKEND_DISABLE.BACKEND_DISABLE per SE */
444 uint32_t backend_disable[4];
445 /** Value of MC_ARB_RAMCFG register*/
446 uint32_t mc_arb_ramcfg;
447 /** Value of GB_ADDR_CONFIG */
448 uint32_t gb_addr_cfg;
449 /** Values of the GB_TILE_MODE0..31 registers */
450 uint32_t gb_tile_mode[32];
451 /** Values of GB_MACROTILE_MODE0..15 registers */
452 uint32_t gb_macro_tile_mode[16];
453 /** Value of PA_SC_RASTER_CONFIG register per SE */
454 uint32_t pa_sc_raster_cfg[4];
455 /** Value of PA_SC_RASTER_CONFIG_1 register per SE */
456 uint32_t pa_sc_raster_cfg1[4];
457 /* CU info */
458 uint32_t cu_active_number;
459 uint32_t cu_ao_mask;
460 uint32_t cu_bitmap[4][4];
461 /* video memory type info*/
462 uint32_t vram_type;
463 /* video memory bit width*/
464 uint32_t vram_bit_width;
465 /** constant engine ram size*/
466 uint32_t ce_ram_size;
467 /* vce harvesting instance */
468 uint32_t vce_harvest_config;
469 /* PCI revision ID */
470 uint32_t pci_rev_id;
471};
472
473
474/*--------------------------------------------------------------------------*/
475/*------------------------- Functions --------------------------------------*/
476/*--------------------------------------------------------------------------*/
477
478/*
479 * Initialization / Cleanup
480 *
481*/
482
483/**
484 *
485 * \param fd - \c [in] File descriptor for AMD GPU device
486 * received previously as the result of
487 * e.g. drmOpen() call.
488 * For legacy fd type, the DRI2/DRI3
489 * authentication should be done before
490 * calling this function.
491 * \param major_version - \c [out] Major version of library. It is assumed
492 * that adding new functionality will cause
493 * increase in major version
494 * \param minor_version - \c [out] Minor version of library
495 * \param device_handle - \c [out] Pointer to opaque context which should
496 * be passed as the first parameter on each
497 * API call
498 *
499 *
500 * \return 0 on success\n
501 * <0 - Negative POSIX Error code
502 *
503 *
504 * \sa amdgpu_device_deinitialize()
505*/
506int amdgpu_device_initialize(int fd,
507 uint32_t *major_version,
508 uint32_t *minor_version,
509 amdgpu_device_handle *device_handle);
510
511/**
512 *
513 * When access to such library does not needed any more the special
514 * function must be call giving opportunity to clean up any
515 * resources if needed.
516 *
517 * \param device_handle - \c [in] Context associated with file
518 * descriptor for AMD GPU device
519 * received previously as the
520 * result e.g. of drmOpen() call.
521 *
522 * \return 0 on success\n
523 * <0 - Negative POSIX Error code
524 *
525 * \sa amdgpu_device_initialize()
526 *
527*/
528int amdgpu_device_deinitialize(amdgpu_device_handle device_handle);
529
530/*
531 * Memory Management
532 *
533*/
534
535/**
536 * Allocate memory to be used by UMD for GPU related operations
537 *
538 * \param dev - \c [in] Device handle.
539 * See #amdgpu_device_initialize()
540 * \param alloc_buffer - \c [in] Pointer to the structure describing an
541 * allocation request
542 * \param buf_handle - \c [out] Allocated buffer handle
543 *
544 * \return 0 on success\n
545 * <0 - Negative POSIX Error code
546 *
547 * \sa amdgpu_bo_free()
548*/
549int amdgpu_bo_alloc(amdgpu_device_handle dev,
550 struct amdgpu_bo_alloc_request *alloc_buffer,
551 amdgpu_bo_handle *buf_handle);
552
553/**
554 * Associate opaque data with buffer to be queried by another UMD
555 *
556 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
557 * \param buf_handle - \c [in] Buffer handle
558 * \param info - \c [in] Metadata to associated with buffer
559 *
560 * \return 0 on success\n
561 * <0 - Negative POSIX Error code
562*/
563int amdgpu_bo_set_metadata(amdgpu_bo_handle buf_handle,
564 struct amdgpu_bo_metadata *info);
565
566/**
567 * Query buffer information including metadata previusly associated with
568 * buffer.
569 *
570 * \param dev - \c [in] Device handle.
571 * See #amdgpu_device_initialize()
572 * \param buf_handle - \c [in] Buffer handle
573 * \param info - \c [out] Structure describing buffer
574 *
575 * \return 0 on success\n
576 * <0 - Negative POSIX Error code
577 *
578 * \sa amdgpu_bo_set_metadata(), amdgpu_bo_alloc()
579*/
580int amdgpu_bo_query_info(amdgpu_bo_handle buf_handle,
581 struct amdgpu_bo_info *info);
582
583/**
584 * Allow others to get access to buffer
585 *
586 * \param dev - \c [in] Device handle.
587 * See #amdgpu_device_initialize()
588 * \param buf_handle - \c [in] Buffer handle
589 * \param type - \c [in] Type of handle requested
590 * \param shared_handle - \c [out] Special "shared" handle
591 *
592 * \return 0 on success\n
593 * <0 - Negative POSIX Error code
594 *
595 * \sa amdgpu_bo_import()
596 *
597*/
598int amdgpu_bo_export(amdgpu_bo_handle buf_handle,
599 enum amdgpu_bo_handle_type type,
600 uint32_t *shared_handle);
601
602/**
603 * Request access to "shared" buffer
604 *
605 * \param dev - \c [in] Device handle.
606 * See #amdgpu_device_initialize()
607 * \param type - \c [in] Type of handle requested
608 * \param shared_handle - \c [in] Shared handle received as result "import"
609 * operation
610 * \param output - \c [out] Pointer to structure with information
611 * about imported buffer
612 *
613 * \return 0 on success\n
614 * <0 - Negative POSIX Error code
615 *
616 * \note Buffer must be "imported" only using new "fd" (different from
617 * one used by "exporter").
618 *
619 * \sa amdgpu_bo_export()
620 *
621*/
622int amdgpu_bo_import(amdgpu_device_handle dev,
623 enum amdgpu_bo_handle_type type,
624 uint32_t shared_handle,
625 struct amdgpu_bo_import_result *output);
626
627/**
628 * Request GPU access to user allocated memory e.g. via "malloc"
629 *
630 * \param dev - [in] Device handle. See #amdgpu_device_initialize()
631 * \param cpu - [in] CPU address of user allocated memory which we
632 * want to map to GPU address space (make GPU accessible)
633 * (This address must be correctly aligned).
634 * \param size - [in] Size of allocation (must be correctly aligned)
635 * \param buf_handle - [out] Buffer handle for the userptr memory
636 * resource on submission and be used in other operations.
637 *
638 *
639 * \return 0 on success\n
640 * <0 - Negative POSIX Error code
641 *
642 * \note
643 * This call doesn't guarantee that such memory will be persistently
644 * "locked" / make non-pageable. The purpose of this call is to provide
645 * opportunity for GPU get access to this resource during submission.
646 *
647 * The maximum amount of memory which could be mapped in this call depends
648 * if overcommit is disabled or not. If overcommit is disabled than the max.
649 * amount of memory to be pinned will be limited by left "free" size in total
650 * amount of memory which could be locked simultaneously ("GART" size).
651 *
652 * Supported (theoretical) max. size of mapping is restricted only by
653 * "GART" size.
654 *
655 * It is responsibility of caller to correctly specify access rights
656 * on VA assignment.
657*/
658int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
659 void *cpu, uint64_t size,
660 amdgpu_bo_handle *buf_handle);
661
662/**
663 * Free previosuly allocated memory
664 *
665 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
666 * \param buf_handle - \c [in] Buffer handle to free
667 *
668 * \return 0 on success\n
669 * <0 - Negative POSIX Error code
670 *
671 * \note In the case of memory shared between different applications all
672 * resources will be “physically” freed only all such applications
673 * will be terminated
674 * \note If is UMD responsibility to ‘free’ buffer only when there is no
675 * more GPU access
676 *
677 * \sa amdgpu_bo_set_metadata(), amdgpu_bo_alloc()
678 *
679*/
680int amdgpu_bo_free(amdgpu_bo_handle buf_handle);
681
682/**
683 * Request CPU access to GPU accessable memory
684 *
685 * \param buf_handle - \c [in] Buffer handle
686 * \param cpu - \c [out] CPU address to be used for access
687 *
688 * \return 0 on success\n
689 * <0 - Negative POSIX Error code
690 *
691 * \sa amdgpu_bo_cpu_unmap()
692 *
693*/
694int amdgpu_bo_cpu_map(amdgpu_bo_handle buf_handle, void **cpu);
695
696/**
697 * Release CPU access to GPU memory
698 *
699 * \param buf_handle - \c [in] Buffer handle
700 *
701 * \return 0 on success\n
702 * <0 - Negative POSIX Error code
703 *
704 * \sa amdgpu_bo_cpu_map()
705 *
706*/
707int amdgpu_bo_cpu_unmap(amdgpu_bo_handle buf_handle);
708
709/**
710 * Wait until a buffer is not used by the device.
711 *
712 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
713 * \param buf_handle - \c [in] Buffer handle.
714 * \param timeout_ns - Timeout in nanoseconds.
715 * \param buffer_busy - 0 if buffer is idle, all GPU access was completed
716 * and no GPU access is scheduled.
717 * 1 GPU access is in fly or scheduled
718 *
719 * \return 0 - on success
720 * <0 - Negative POSIX Error code
721 */
722int amdgpu_bo_wait_for_idle(amdgpu_bo_handle buf_handle,
723 uint64_t timeout_ns,
724 bool *buffer_busy);
725
726/**
727 * Creates a BO list handle for command submission.
728 *
729 * \param dev - \c [in] Device handle.
730 * See #amdgpu_device_initialize()
731 * \param number_of_resources - \c [in] Number of BOs in the list
732 * \param resources - \c [in] List of BO handles
733 * \param resource_prios - \c [in] Optional priority for each handle
734 * \param result - \c [out] Created BO list handle
735 *
736 * \return 0 on success\n
737 * <0 - Negative POSIX Error code
738 *
739 * \sa amdgpu_bo_list_destroy()
740*/
741int amdgpu_bo_list_create(amdgpu_device_handle dev,
742 uint32_t number_of_resources,
743 amdgpu_bo_handle *resources,
744 uint8_t *resource_prios,
745 amdgpu_bo_list_handle *result);
746
747/**
748 * Destroys a BO list handle.
749 *
750 * \param handle - \c [in] BO list handle.
751 *
752 * \return 0 on success\n
753 * <0 - Negative POSIX Error code
754 *
755 * \sa amdgpu_bo_list_create()
756*/
757int amdgpu_bo_list_destroy(amdgpu_bo_list_handle handle);
758
759/**
760 * Update resources for existing BO list
761 *
762 * \param handle - \c [in] BO list handle
763 * \param number_of_resources - \c [in] Number of BOs in the list
764 * \param resources - \c [in] List of BO handles
765 * \param resource_prios - \c [in] Optional priority for each handle
766 *
767 * \return 0 on success\n
768 * <0 - Negative POSIX Error code
769 *
770 * \sa amdgpu_bo_list_update()
771*/
772int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
773 uint32_t number_of_resources,
774 amdgpu_bo_handle *resources,
775 uint8_t *resource_prios);
776
777/*
778 * GPU Execution context
779 *
780*/
781
782/**
783 * Create GPU execution Context
784 *
785 * For the purpose of GPU Scheduler and GPU Robustness extensions it is
786 * necessary to have information/identify rendering/compute contexts.
787 * It also may be needed to associate some specific requirements with such
788 * contexts. Kernel driver will guarantee that submission from the same
789 * context will always be executed in order (first come, first serve).
790 *
791 *
792 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
793 * \param context - \c [out] GPU Context handle
794 *
795 * \return 0 on success\n
796 * <0 - Negative POSIX Error code
797 *
798 * \sa amdgpu_cs_ctx_free()
799 *
800*/
801int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
802 amdgpu_context_handle *context);
803
804/**
805 *
806 * Destroy GPU execution context when not needed any more
807 *
808 * \param context - \c [in] GPU Context handle
809 *
810 * \return 0 on success\n
811 * <0 - Negative POSIX Error code
812 *
813 * \sa amdgpu_cs_ctx_create()
814 *
815*/
816int amdgpu_cs_ctx_free(amdgpu_context_handle context);
817
818/**
819 * Query reset state for the specific GPU Context
820 *
821 * \param context - \c [in] GPU Context handle
822 * \param state - \c [out] One of AMDGPU_CTX_*_RESET
823 * \param hangs - \c [out] Number of hangs caused by the context.
824 *
825 * \return 0 on success\n
826 * <0 - Negative POSIX Error code
827 *
828 * \sa amdgpu_cs_ctx_create()
829 *
830*/
831int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
832 uint32_t *state, uint32_t *hangs);
833
834/*
835 * Command Buffers Management
836 *
837*/
838
839/**
840 * Send request to submit command buffers to hardware.
841 *
842 * Kernel driver could use GPU Scheduler to make decision when physically
843 * sent this request to the hardware. Accordingly this request could be put
844 * in queue and sent for execution later. The only guarantee is that request
845 * from the same GPU context to the same ip:ip_instance:ring will be executed in
846 * order.
847 *
848 * The caller can specify the user fence buffer/location with the fence_info in the
849 * cs_request.The sequence number is returned via the 'seq_no' paramter
850 * in ibs_request structure.
851 *
852 *
853 * \param dev - \c [in] Device handle.
854 * See #amdgpu_device_initialize()
855 * \param context - \c [in] GPU Context
856 * \param flags - \c [in] Global submission flags
857 * \param ibs_request - \c [in/out] Pointer to submission requests.
858 * We could submit to the several
859 * engines/rings simulteniously as
860 * 'atomic' operation
861 * \param number_of_requests - \c [in] Number of submission requests
862 *
863 * \return 0 on success\n
864 * <0 - Negative POSIX Error code
865 *
866 * \note It is required to pass correct resource list with buffer handles
867 * which will be accessible by command buffers from submission
868 * This will allow kernel driver to correctly implement "paging".
869 * Failure to do so will have unpredictable results.
870 *
871 * \sa amdgpu_command_buffer_alloc(), amdgpu_command_buffer_free(),
872 * amdgpu_cs_query_fence_status()
873 *
874*/
875int amdgpu_cs_submit(amdgpu_context_handle context,
876 uint64_t flags,
877 struct amdgpu_cs_request *ibs_request,
878 uint32_t number_of_requests);
879
880/**
881 * Query status of Command Buffer Submission
882 *
883 * \param fence - \c [in] Structure describing fence to query
884 * \param timeout_ns - \c [in] Timeout value to wait
885 * \param flags - \c [in] Flags for the query
886 * \param expired - \c [out] If fence expired or not.\n
887 * 0 – if fence is not expired\n
888 * !0 - otherwise
889 *
890 * \return 0 on success\n
891 * <0 - Negative POSIX Error code
892 *
893 * \note If UMD wants only to check operation status and returned immediately
894 * then timeout value as 0 must be passed. In this case success will be
895 * returned in the case if submission was completed or timeout error
896 * code.
897 *
898 * \sa amdgpu_cs_submit()
899*/
900int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence,
901 uint64_t timeout_ns,
902 uint64_t flags,
903 uint32_t *expired);
904
905/*
906 * Query / Info API
907 *
908*/
909
910/**
911 * Query allocation size alignments
912 *
913 * UMD should query information about GPU VM MC size alignments requirements
914 * to be able correctly choose required allocation size and implement
915 * internal optimization if needed.
916 *
917 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
918 * \param info - \c [out] Pointer to structure to get size alignment
919 * requirements
920 *
921 * \return 0 on success\n
922 * <0 - Negative POSIX Error code
923 *
924*/
925int amdgpu_query_buffer_size_alignment(amdgpu_device_handle dev,
926 struct amdgpu_buffer_size_alignments
927 *info);
928
929/**
930 * Query firmware versions
931 *
932 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
933 * \param fw_type - \c [in] AMDGPU_INFO_FW_*
934 * \param ip_instance - \c [in] Index of the IP block of the same type.
935 * \param index - \c [in] Index of the engine. (for SDMA and MEC)
936 * \param version - \c [out] Pointer to to the "version" return value
937 * \param feature - \c [out] Pointer to to the "feature" return value
938 *
939 * \return 0 on success\n
940 * <0 - Negative POSIX Error code
941 *
942*/
943int amdgpu_query_firmware_version(amdgpu_device_handle dev, unsigned fw_type,
944 unsigned ip_instance, unsigned index,
945 uint32_t *version, uint32_t *feature);
946
947/**
948 * Query the number of HW IP instances of a certain type.
949 *
950 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
951 * \param type - \c [in] Hardware IP block type = AMDGPU_HW_IP_*
952 * \param count - \c [out] Pointer to structure to get information
953 *
954 * \return 0 on success\n
955 * <0 - Negative POSIX Error code
956*/
957int amdgpu_query_hw_ip_count(amdgpu_device_handle dev, unsigned type,
958 uint32_t *count);
959
960/**
961 * Query engine information
962 *
963 * This query allows UMD to query information different engines and their
964 * capabilities.
965 *
966 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
967 * \param type - \c [in] Hardware IP block type = AMDGPU_HW_IP_*
968 * \param ip_instance - \c [in] Index of the IP block of the same type.
969 * \param info - \c [out] Pointer to structure to get information
970 *
971 * \return 0 on success\n
972 * <0 - Negative POSIX Error code
973*/
974int amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type,
975 unsigned ip_instance,
976 struct drm_amdgpu_info_hw_ip *info);
977
978/**
979 * Query heap information
980 *
981 * This query allows UMD to query potentially available memory resources and
982 * adjust their logic if necessary.
983 *
984 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
985 * \param heap - \c [in] Heap type
986 * \param info - \c [in] Pointer to structure to get needed information
987 *
988 * \return 0 on success\n
989 * <0 - Negative POSIX Error code
990 *
991*/
992int amdgpu_query_heap_info(amdgpu_device_handle dev, uint32_t heap,
993 uint32_t flags, struct amdgpu_heap_info *info);
994
995/**
996 * Get the CRTC ID from the mode object ID
997 *
998 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
999 * \param id - \c [in] Mode object ID
1000 * \param result - \c [in] Pointer to the CRTC ID
1001 *
1002 * \return 0 on success\n
1003 * <0 - Negative POSIX Error code
1004 *
1005*/
1006int amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id,
1007 int32_t *result);
1008
1009/**
1010 * Query GPU H/w Info
1011 *
1012 * Query hardware specific information
1013 *
1014 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
1015 * \param heap - \c [in] Heap type
1016 * \param info - \c [in] Pointer to structure to get needed information
1017 *
1018 * \return 0 on success\n
1019 * <0 - Negative POSIX Error code
1020 *
1021*/
1022int amdgpu_query_gpu_info(amdgpu_device_handle dev,
1023 struct amdgpu_gpu_info *info);
1024
1025/**
1026 * Query hardware or driver information.
1027 *
1028 * The return size is query-specific and depends on the "info_id" parameter.
1029 * No more than "size" bytes is returned.
1030 *
1031 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
1032 * \param info_id - \c [in] AMDGPU_INFO_*
1033 * \param size - \c [in] Size of the returned value.
1034 * \param value - \c [out] Pointer to the return value.
1035 *
1036 * \return 0 on success\n
1037 * <0 - Negative POSIX error code
1038 *
1039*/
1040int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
1041 unsigned size, void *value);
1042
1043/**
1044 * Query information about GDS
1045 *
1046 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
1047 * \param gds_info - \c [out] Pointer to structure to get GDS information
1048 *
1049 * \return 0 on success\n
1050 * <0 - Negative POSIX Error code
1051 *
1052*/
1053int amdgpu_query_gds_info(amdgpu_device_handle dev,
1054 struct amdgpu_gds_resource_info *gds_info);
1055
1056/**
1057 * Read a set of consecutive memory-mapped registers.
1058 * Not all registers are allowed to be read by userspace.
1059 *
1060 * \param dev - \c [in] Device handle. See #amdgpu_device_initialize(
1061 * \param dword_offset - \c [in] Register offset in dwords
1062 * \param count - \c [in] The number of registers to read starting
1063 * from the offset
1064 * \param instance - \c [in] GRBM_GFX_INDEX selector. It may have other
1065 * uses. Set it to 0xffffffff if unsure.
1066 * \param flags - \c [in] Flags with additional information.
1067 * \param values - \c [out] The pointer to return values.
1068 *
1069 * \return 0 on success\n
1070 * <0 - Negative POSIX error code
1071 *
1072*/
1073int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset,
1074 unsigned count, uint32_t instance, uint32_t flags,
1075 uint32_t *values);
1076
1077/**
1078 * Flag to request VA address range in the 32bit address space
1079*/
1080#define AMDGPU_VA_RANGE_32_BIT 0x1
1081
1082/**
1083 * Allocate virtual address range
1084 *
1085 * \param dev - [in] Device handle. See #amdgpu_device_initialize()
1086 * \param va_range_type - \c [in] Type of MC va range from which to allocate
1087 * \param size - \c [in] Size of range. Size must be correctly* aligned.
1088 * It is client responsibility to correctly aligned size based on the future
1089 * usage of allocated range.
1090 * \param va_base_alignment - \c [in] Overwrite base address alignment
1091 * requirement for GPU VM MC virtual
1092 * address assignment. Must be multiple of size alignments received as
1093 * 'amdgpu_buffer_size_alignments'.
1094 * If 0 use the default one.
1095 * \param va_base_required - \c [in] Specified required va base address.
1096 * If 0 then library choose available one.
1097 * If !0 value will be passed and those value already "in use" then
1098 * corresponding error status will be returned.
1099 * \param va_base_allocated - \c [out] On return: Allocated VA base to be used
1100 * by client.
1101 * \param va_range_handle - \c [out] On return: Handle assigned to allocation
1102 * \param flags - \c [in] flags for special VA range
1103 *
1104 * \return 0 on success\n
1105 * >0 - AMD specific error code\n
1106 * <0 - Negative POSIX Error code
1107 *
1108 * \notes \n
1109 * It is client responsibility to correctly handle VA assignments and usage.
1110 * Neither kernel driver nor libdrm_amdpgu are able to prevent and
1111 * detect wrong va assignemnt.
1112 *
1113 * It is client responsibility to correctly handle multi-GPU cases and to pass
1114 * the corresponding arrays of all devices handles where corresponding VA will
1115 * be used.
1116 *
1117*/
1118int amdgpu_va_range_alloc(amdgpu_device_handle dev,
1119 enum amdgpu_gpu_va_range va_range_type,
1120 uint64_t size,
1121 uint64_t va_base_alignment,
1122 uint64_t va_base_required,
1123 uint64_t *va_base_allocated,
1124 amdgpu_va_handle *va_range_handle,
1125 uint64_t flags);
1126
1127/**
1128 * Free previously allocated virtual address range
1129 *
1130 *
1131 * \param va_range_handle - \c [in] Handle assigned to VA allocation
1132 *
1133 * \return 0 on success\n
1134 * >0 - AMD specific error code\n
1135 * <0 - Negative POSIX Error code
1136 *
1137*/
1138int amdgpu_va_range_free(amdgpu_va_handle va_range_handle);
1139
1140/**
1141* Query virtual address range
1142*
1143* UMD can query GPU VM range supported by each device
1144* to initialize its own VAM accordingly.
1145*
1146* \param dev - [in] Device handle. See #amdgpu_device_initialize()
1147* \param type - \c [in] Type of virtual address range
1148* \param offset - \c [out] Start offset of virtual address range
1149* \param size - \c [out] Size of virtual address range
1150*
1151* \return 0 on success\n
1152* <0 - Negative POSIX Error code
1153*
1154*/
1155
1156int amdgpu_va_range_query(amdgpu_device_handle dev,
1157 enum amdgpu_gpu_va_range type,
1158 uint64_t *start,
1159 uint64_t *end);
1160
1161/**
1162 * VA mapping/unmapping for the buffer object
1163 *
1164 * \param bo - \c [in] BO handle
1165 * \param offset - \c [in] Start offset to map
1166 * \param size - \c [in] Size to map
1167 * \param addr - \c [in] Start virtual address.
1168 * \param flags - \c [in] Supported flags for mapping/unmapping
1169 * \param ops - \c [in] AMDGPU_VA_OP_MAP or AMDGPU_VA_OP_UNMAP
1170 *
1171 * \return 0 on success\n
1172 * <0 - Negative POSIX Error code
1173 *
1174*/
1175
1176int amdgpu_bo_va_op(amdgpu_bo_handle bo,
1177 uint64_t offset,
1178 uint64_t size,
1179 uint64_t addr,
1180 uint64_t flags,
1181 uint32_t ops);
1182
1183#endif /* #ifdef _AMDGPU_H_ */
diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c
new file mode 100644
index 00000000..1a5a4011
--- /dev/null
+++ b/amdgpu/amdgpu_bo.c
@@ -0,0 +1,713 @@
1/*
2 * Copyright © 2014 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <stdlib.h>
30#include <stdio.h>
31#include <stdint.h>
32#include <string.h>
33#include <errno.h>
34#include <fcntl.h>
35#include <unistd.h>
36#include <sys/ioctl.h>
37#include <sys/mman.h>
38#include <sys/time.h>
39
40#include "libdrm_macros.h"
41#include "xf86drm.h"
42#include "amdgpu_drm.h"
43#include "amdgpu_internal.h"
44#include "util_hash_table.h"
45#include "util_math.h"
46
47static void amdgpu_close_kms_handle(amdgpu_device_handle dev,
48 uint32_t handle)
49{
50 struct drm_gem_close args = {};
51
52 args.handle = handle;
53 drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &args);
54}
55
56drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo)
57{
58 /* Remove the buffer from the hash tables. */
59 pthread_mutex_lock(&bo->dev->bo_table_mutex);
60 util_hash_table_remove(bo->dev->bo_handles,
61 (void*)(uintptr_t)bo->handle);
62 if (bo->flink_name) {
63 util_hash_table_remove(bo->dev->bo_flink_names,
64 (void*)(uintptr_t)bo->flink_name);
65 }
66 pthread_mutex_unlock(&bo->dev->bo_table_mutex);
67
68 /* Release CPU access. */
69 if (bo->cpu_map_count > 0) {
70 bo->cpu_map_count = 1;
71 amdgpu_bo_cpu_unmap(bo);
72 }
73
74 amdgpu_close_kms_handle(bo->dev, bo->handle);
75 pthread_mutex_destroy(&bo->cpu_access_mutex);
76 free(bo);
77}
78
79int amdgpu_bo_alloc(amdgpu_device_handle dev,
80 struct amdgpu_bo_alloc_request *alloc_buffer,
81 amdgpu_bo_handle *buf_handle)
82{
83 struct amdgpu_bo *bo;
84 union drm_amdgpu_gem_create args;
85 unsigned heap = alloc_buffer->preferred_heap;
86 int r = 0;
87
88 /* It's an error if the heap is not specified */
89 if (!(heap & (AMDGPU_GEM_DOMAIN_GTT | AMDGPU_GEM_DOMAIN_VRAM)))
90 return -EINVAL;
91
92 bo = calloc(1, sizeof(struct amdgpu_bo));
93 if (!bo)
94 return -ENOMEM;
95
96 atomic_set(&bo->refcount, 1);
97 bo->dev = dev;
98 bo->alloc_size = alloc_buffer->alloc_size;
99
100 memset(&args, 0, sizeof(args));
101 args.in.bo_size = alloc_buffer->alloc_size;
102 args.in.alignment = alloc_buffer->phys_alignment;
103
104 /* Set the placement. */
105 args.in.domains = heap;
106 args.in.domain_flags = alloc_buffer->flags;
107
108 /* Allocate the buffer with the preferred heap. */
109 r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_CREATE,
110 &args, sizeof(args));
111 if (r) {
112 free(bo);
113 return r;
114 }
115
116 bo->handle = args.out.handle;
117
118 pthread_mutex_init(&bo->cpu_access_mutex, NULL);
119
120 *buf_handle = bo;
121 return 0;
122}
123
124int amdgpu_bo_set_metadata(amdgpu_bo_handle bo,
125 struct amdgpu_bo_metadata *info)
126{
127 struct drm_amdgpu_gem_metadata args = {};
128
129 args.handle = bo->handle;
130 args.op = AMDGPU_GEM_METADATA_OP_SET_METADATA;
131 args.data.flags = info->flags;
132 args.data.tiling_info = info->tiling_info;
133
134 if (info->size_metadata > sizeof(args.data.data))
135 return -EINVAL;
136
137 if (info->size_metadata) {
138 args.data.data_size_bytes = info->size_metadata;
139 memcpy(args.data.data, info->umd_metadata, info->size_metadata);
140 }
141
142 return drmCommandWriteRead(bo->dev->fd,
143 DRM_AMDGPU_GEM_METADATA,
144 &args, sizeof(args));
145}
146
147int amdgpu_bo_query_info(amdgpu_bo_handle bo,
148 struct amdgpu_bo_info *info)
149{
150 struct drm_amdgpu_gem_metadata metadata = {};
151 struct drm_amdgpu_gem_create_in bo_info = {};
152 struct drm_amdgpu_gem_op gem_op = {};
153 int r;
154
155 /* Validate the BO passed in */
156 if (!bo->handle)
157 return -EINVAL;
158
159 /* Query metadata. */
160 metadata.handle = bo->handle;
161 metadata.op = AMDGPU_GEM_METADATA_OP_GET_METADATA;
162
163 r = drmCommandWriteRead(bo->dev->fd, DRM_AMDGPU_GEM_METADATA,
164 &metadata, sizeof(metadata));
165 if (r)
166 return r;
167
168 if (metadata.data.data_size_bytes >
169 sizeof(info->metadata.umd_metadata))
170 return -EINVAL;
171
172 /* Query buffer info. */
173 gem_op.handle = bo->handle;
174 gem_op.op = AMDGPU_GEM_OP_GET_GEM_CREATE_INFO;
175 gem_op.value = (uintptr_t)&bo_info;
176
177 r = drmCommandWriteRead(bo->dev->fd, DRM_AMDGPU_GEM_OP,
178 &gem_op, sizeof(gem_op));
179 if (r)
180 return r;
181
182 memset(info, 0, sizeof(*info));
183 info->alloc_size = bo_info.bo_size;
184 info->phys_alignment = bo_info.alignment;
185 info->preferred_heap = bo_info.domains;
186 info->alloc_flags = bo_info.domain_flags;
187 info->metadata.flags = metadata.data.flags;
188 info->metadata.tiling_info = metadata.data.tiling_info;
189
190 info->metadata.size_metadata = metadata.data.data_size_bytes;
191 if (metadata.data.data_size_bytes > 0)
192 memcpy(info->metadata.umd_metadata, metadata.data.data,
193 metadata.data.data_size_bytes);
194
195 return 0;
196}
197
198static void amdgpu_add_handle_to_table(amdgpu_bo_handle bo)
199{
200 pthread_mutex_lock(&bo->dev->bo_table_mutex);
201 util_hash_table_set(bo->dev->bo_handles,
202 (void*)(uintptr_t)bo->handle, bo);
203 pthread_mutex_unlock(&bo->dev->bo_table_mutex);
204}
205
206static int amdgpu_bo_export_flink(amdgpu_bo_handle bo)
207{
208 struct drm_gem_flink flink;
209 int fd, dma_fd;
210 uint32_t handle;
211 int r;
212
213 fd = bo->dev->fd;
214 handle = bo->handle;
215 if (bo->flink_name)
216 return 0;
217
218
219 if (bo->dev->flink_fd != bo->dev->fd) {
220 r = drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC,
221 &dma_fd);
222 if (!r) {
223 r = drmPrimeFDToHandle(bo->dev->flink_fd, dma_fd, &handle);
224 close(dma_fd);
225 }
226 if (r)
227 return r;
228 fd = bo->dev->flink_fd;
229 }
230 memset(&flink, 0, sizeof(flink));
231 flink.handle = handle;
232
233 r = drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
234 if (r)
235 return r;
236
237 bo->flink_name = flink.name;
238
239 if (bo->dev->flink_fd != bo->dev->fd) {
240 struct drm_gem_close args = {};
241 args.handle = handle;
242 drmIoctl(bo->dev->flink_fd, DRM_IOCTL_GEM_CLOSE, &args);
243 }
244
245 pthread_mutex_lock(&bo->dev->bo_table_mutex);
246 util_hash_table_set(bo->dev->bo_flink_names,
247 (void*)(uintptr_t)bo->flink_name,
248 bo);
249 pthread_mutex_unlock(&bo->dev->bo_table_mutex);
250
251 return 0;
252}
253
254int amdgpu_bo_export(amdgpu_bo_handle bo,
255 enum amdgpu_bo_handle_type type,
256 uint32_t *shared_handle)
257{
258 int r;
259
260 switch (type) {
261 case amdgpu_bo_handle_type_gem_flink_name:
262 r = amdgpu_bo_export_flink(bo);
263 if (r)
264 return r;
265
266 *shared_handle = bo->flink_name;
267 return 0;
268
269 case amdgpu_bo_handle_type_kms:
270 amdgpu_add_handle_to_table(bo);
271 *shared_handle = bo->handle;
272 return 0;
273
274 case amdgpu_bo_handle_type_dma_buf_fd:
275 amdgpu_add_handle_to_table(bo);
276 return drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC,
277 (int*)shared_handle);
278 }
279 return -EINVAL;
280}
281
282int amdgpu_bo_import(amdgpu_device_handle dev,
283 enum amdgpu_bo_handle_type type,
284 uint32_t shared_handle,
285 struct amdgpu_bo_import_result *output)
286{
287 struct drm_gem_open open_arg = {};
288 struct amdgpu_bo *bo = NULL;
289 int r;
290 int dma_fd;
291 uint64_t dma_buf_size = 0;
292
293 /* We must maintain a list of pairs <handle, bo>, so that we always
294 * return the same amdgpu_bo instance for the same handle. */
295 pthread_mutex_lock(&dev->bo_table_mutex);
296
297 /* Convert a DMA buf handle to a KMS handle now. */
298 if (type == amdgpu_bo_handle_type_dma_buf_fd) {
299 uint32_t handle;
300 off_t size;
301
302 /* Get a KMS handle. */
303 r = drmPrimeFDToHandle(dev->fd, shared_handle, &handle);
304 if (r) {
305 return r;
306 }
307
308 /* Query the buffer size. */
309 size = lseek(shared_handle, 0, SEEK_END);
310 if (size == (off_t)-1) {
311 pthread_mutex_unlock(&dev->bo_table_mutex);
312 amdgpu_close_kms_handle(dev, handle);
313 return -errno;
314 }
315 lseek(shared_handle, 0, SEEK_SET);
316
317 dma_buf_size = size;
318 shared_handle = handle;
319 }
320
321 /* If we have already created a buffer with this handle, find it. */
322 switch (type) {
323 case amdgpu_bo_handle_type_gem_flink_name:
324 bo = util_hash_table_get(dev->bo_flink_names,
325 (void*)(uintptr_t)shared_handle);
326 break;
327
328 case amdgpu_bo_handle_type_dma_buf_fd:
329 bo = util_hash_table_get(dev->bo_handles,
330 (void*)(uintptr_t)shared_handle);
331 break;
332
333 case amdgpu_bo_handle_type_kms:
334 /* Importing a KMS handle in not allowed. */
335 pthread_mutex_unlock(&dev->bo_table_mutex);
336 return -EPERM;
337
338 default:
339 pthread_mutex_unlock(&dev->bo_table_mutex);
340 return -EINVAL;
341 }
342
343 if (bo) {
344 pthread_mutex_unlock(&dev->bo_table_mutex);
345
346 /* The buffer already exists, just bump the refcount. */
347 atomic_inc(&bo->refcount);
348
349 output->buf_handle = bo;
350 output->alloc_size = bo->alloc_size;
351 return 0;
352 }
353
354 bo = calloc(1, sizeof(struct amdgpu_bo));
355 if (!bo) {
356 pthread_mutex_unlock(&dev->bo_table_mutex);
357 if (type == amdgpu_bo_handle_type_dma_buf_fd) {
358 amdgpu_close_kms_handle(dev, shared_handle);
359 }
360 return -ENOMEM;
361 }
362
363 /* Open the handle. */
364 switch (type) {
365 case amdgpu_bo_handle_type_gem_flink_name:
366 open_arg.name = shared_handle;
367 r = drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_OPEN, &open_arg);
368 if (r) {
369 free(bo);
370 pthread_mutex_unlock(&dev->bo_table_mutex);
371 return r;
372 }
373
374 bo->handle = open_arg.handle;
375 if (dev->flink_fd != dev->fd) {
376 r = drmPrimeHandleToFD(dev->flink_fd, bo->handle, DRM_CLOEXEC, &dma_fd);
377 if (r) {
378 free(bo);
379 pthread_mutex_unlock(&dev->bo_table_mutex);
380 return r;
381 }
382 r = drmPrimeFDToHandle(dev->fd, dma_fd, &bo->handle );
383
384 close(dma_fd);
385
386 if (r) {
387 free(bo);
388 pthread_mutex_unlock(&dev->bo_table_mutex);
389 return r;
390 }
391 }
392 bo->flink_name = shared_handle;
393 bo->alloc_size = open_arg.size;
394 util_hash_table_set(dev->bo_flink_names,
395 (void*)(uintptr_t)bo->flink_name, bo);
396 break;
397
398 case amdgpu_bo_handle_type_dma_buf_fd:
399 bo->handle = shared_handle;
400 bo->alloc_size = dma_buf_size;
401 break;
402
403 case amdgpu_bo_handle_type_kms:
404 assert(0); /* unreachable */
405 }
406
407 /* Initialize it. */
408 atomic_set(&bo->refcount, 1);
409 bo->dev = dev;
410 pthread_mutex_init(&bo->cpu_access_mutex, NULL);
411
412 util_hash_table_set(dev->bo_handles, (void*)(uintptr_t)bo->handle, bo);
413 pthread_mutex_unlock(&dev->bo_table_mutex);
414
415 output->buf_handle = bo;
416 output->alloc_size = bo->alloc_size;
417 return 0;
418}
419
420int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
421{
422 /* Just drop the reference. */
423 amdgpu_bo_reference(&buf_handle, NULL);
424 return 0;
425}
426
427int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu)
428{
429 union drm_amdgpu_gem_mmap args;
430 void *ptr;
431 int r;
432
433 pthread_mutex_lock(&bo->cpu_access_mutex);
434
435 if (bo->cpu_ptr) {
436 /* already mapped */
437 assert(bo->cpu_map_count > 0);
438 bo->cpu_map_count++;
439 *cpu = bo->cpu_ptr;
440 pthread_mutex_unlock(&bo->cpu_access_mutex);
441 return 0;
442 }
443
444 assert(bo->cpu_map_count == 0);
445
446 memset(&args, 0, sizeof(args));
447
448 /* Query the buffer address (args.addr_ptr).
449 * The kernel driver ignores the offset and size parameters. */
450 args.in.handle = bo->handle;
451
452 r = drmCommandWriteRead(bo->dev->fd, DRM_AMDGPU_GEM_MMAP, &args,
453 sizeof(args));
454 if (r) {
455 pthread_mutex_unlock(&bo->cpu_access_mutex);
456 return r;
457 }
458
459 /* Map the buffer. */
460 ptr = drm_mmap(NULL, bo->alloc_size, PROT_READ | PROT_WRITE, MAP_SHARED,
461 bo->dev->fd, args.out.addr_ptr);
462 if (ptr == MAP_FAILED) {
463 pthread_mutex_unlock(&bo->cpu_access_mutex);
464 return -errno;
465 }
466
467 bo->cpu_ptr = ptr;
468 bo->cpu_map_count = 1;
469 pthread_mutex_unlock(&bo->cpu_access_mutex);
470
471 *cpu = ptr;
472 return 0;
473}
474
475int amdgpu_bo_cpu_unmap(amdgpu_bo_handle bo)
476{
477 int r;
478
479 pthread_mutex_lock(&bo->cpu_access_mutex);
480 assert(bo->cpu_map_count >= 0);
481
482 if (bo->cpu_map_count == 0) {
483 /* not mapped */
484 pthread_mutex_unlock(&bo->cpu_access_mutex);
485 return -EINVAL;
486 }
487
488 bo->cpu_map_count--;
489 if (bo->cpu_map_count > 0) {
490 /* mapped multiple times */
491 pthread_mutex_unlock(&bo->cpu_access_mutex);
492 return 0;
493 }
494
495 r = drm_munmap(bo->cpu_ptr, bo->alloc_size) == 0 ? 0 : -errno;
496 bo->cpu_ptr = NULL;
497 pthread_mutex_unlock(&bo->cpu_access_mutex);
498 return r;
499}
500
501int amdgpu_query_buffer_size_alignment(amdgpu_device_handle dev,
502 struct amdgpu_buffer_size_alignments *info)
503{
504 info->size_local = dev->dev_info.pte_fragment_size;
505 info->size_remote = dev->dev_info.gart_page_size;
506 return 0;
507}
508
509int amdgpu_bo_wait_for_idle(amdgpu_bo_handle bo,
510 uint64_t timeout_ns,
511 bool *busy)
512{
513 union drm_amdgpu_gem_wait_idle args;
514 int r;
515
516 memset(&args, 0, sizeof(args));
517 args.in.handle = bo->handle;
518 args.in.timeout = amdgpu_cs_calculate_timeout(timeout_ns);
519
520 r = drmCommandWriteRead(bo->dev->fd, DRM_AMDGPU_GEM_WAIT_IDLE,
521 &args, sizeof(args));
522
523 if (r == 0) {
524 *busy = args.out.status;
525 return 0;
526 } else {
527 fprintf(stderr, "amdgpu: GEM_WAIT_IDLE failed with %i\n", r);
528 return r;
529 }
530}
531
532int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
533 void *cpu,
534 uint64_t size,
535 amdgpu_bo_handle *buf_handle)
536{
537 int r;
538 struct amdgpu_bo *bo;
539 struct drm_amdgpu_gem_userptr args;
540 uintptr_t cpu0;
541 uint32_t ps, off;
542
543 memset(&args, 0, sizeof(args));
544 ps = getpagesize();
545
546 cpu0 = ROUND_DOWN((uintptr_t)cpu, ps);
547 off = (uintptr_t)cpu - cpu0;
548 size = ROUND_UP(size + off, ps);
549
550 args.addr = cpu0;
551 args.flags = AMDGPU_GEM_USERPTR_ANONONLY | AMDGPU_GEM_USERPTR_REGISTER;
552 args.size = size;
553 r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_USERPTR,
554 &args, sizeof(args));
555 if (r)
556 return r;
557
558 bo = calloc(1, sizeof(struct amdgpu_bo));
559 if (!bo)
560 return -ENOMEM;
561
562 atomic_set(&bo->refcount, 1);
563 bo->dev = dev;
564 bo->alloc_size = size;
565 bo->handle = args.handle;
566
567 *buf_handle = bo;
568
569 return r;
570}
571
572int amdgpu_bo_list_create(amdgpu_device_handle dev,
573 uint32_t number_of_resources,
574 amdgpu_bo_handle *resources,
575 uint8_t *resource_prios,
576 amdgpu_bo_list_handle *result)
577{
578 struct drm_amdgpu_bo_list_entry *list;
579 union drm_amdgpu_bo_list args;
580 unsigned i;
581 int r;
582
583 if (!number_of_resources)
584 return -EINVAL;
585
586 /* overflow check for multiplication */
587 if (number_of_resources > UINT32_MAX / sizeof(struct drm_amdgpu_bo_list_entry))
588 return -EINVAL;
589
590 list = malloc(number_of_resources * sizeof(struct drm_amdgpu_bo_list_entry));
591 if (!list)
592 return -ENOMEM;
593
594 *result = malloc(sizeof(struct amdgpu_bo_list));
595 if (!*result) {
596 free(list);
597 return -ENOMEM;
598 }
599
600 memset(&args, 0, sizeof(args));
601 args.in.operation = AMDGPU_BO_LIST_OP_CREATE;
602 args.in.bo_number = number_of_resources;
603 args.in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
604 args.in.bo_info_ptr = (uint64_t)(uintptr_t)list;
605
606 for (i = 0; i < number_of_resources; i++) {
607 list[i].bo_handle = resources[i]->handle;
608 if (resource_prios)
609 list[i].bo_priority = resource_prios[i];
610 else
611 list[i].bo_priority = 0;
612 }
613
614 r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_BO_LIST,
615 &args, sizeof(args));
616 free(list);
617 if (r) {
618 free(*result);
619 return r;
620 }
621
622 (*result)->dev = dev;
623 (*result)->handle = args.out.list_handle;
624 return 0;
625}
626
627int amdgpu_bo_list_destroy(amdgpu_bo_list_handle list)
628{
629 union drm_amdgpu_bo_list args;
630 int r;
631
632 memset(&args, 0, sizeof(args));
633 args.in.operation = AMDGPU_BO_LIST_OP_DESTROY;
634 args.in.list_handle = list->handle;
635
636 r = drmCommandWriteRead(list->dev->fd, DRM_AMDGPU_BO_LIST,
637 &args, sizeof(args));
638
639 if (!r)
640 free(list);
641
642 return r;
643}
644
645int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
646 uint32_t number_of_resources,
647 amdgpu_bo_handle *resources,
648 uint8_t *resource_prios)
649{
650 struct drm_amdgpu_bo_list_entry *list;
651 union drm_amdgpu_bo_list args;
652 unsigned i;
653 int r;
654
655 if (!number_of_resources)
656 return -EINVAL;
657
658 /* overflow check for multiplication */
659 if (number_of_resources > UINT32_MAX / sizeof(struct drm_amdgpu_bo_list_entry))
660 return -EINVAL;
661
662 list = malloc(number_of_resources * sizeof(struct drm_amdgpu_bo_list_entry));
663 if (list == NULL)
664 return -ENOMEM;
665
666 args.in.operation = AMDGPU_BO_LIST_OP_UPDATE;
667 args.in.list_handle = handle->handle;
668 args.in.bo_number = number_of_resources;
669 args.in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
670 args.in.bo_info_ptr = (uintptr_t)list;
671
672 for (i = 0; i < number_of_resources; i++) {
673 list[i].bo_handle = resources[i]->handle;
674 if (resource_prios)
675 list[i].bo_priority = resource_prios[i];
676 else
677 list[i].bo_priority = 0;
678 }
679
680 r = drmCommandWriteRead(handle->dev->fd, DRM_AMDGPU_BO_LIST,
681 &args, sizeof(args));
682 free(list);
683 return r;
684}
685
686int amdgpu_bo_va_op(amdgpu_bo_handle bo,
687 uint64_t offset,
688 uint64_t size,
689 uint64_t addr,
690 uint64_t flags,
691 uint32_t ops)
692{
693 amdgpu_device_handle dev = bo->dev;
694 struct drm_amdgpu_gem_va va;
695 int r;
696
697 if (ops != AMDGPU_VA_OP_MAP && ops != AMDGPU_VA_OP_UNMAP)
698 return -EINVAL;
699
700 memset(&va, 0, sizeof(va));
701 va.handle = bo->handle;
702 va.operation = ops;
703 va.flags = AMDGPU_VM_PAGE_READABLE |
704 AMDGPU_VM_PAGE_WRITEABLE |
705 AMDGPU_VM_PAGE_EXECUTABLE;
706 va.va_address = addr;
707 va.offset_in_bo = offset;
708 va.map_size = ALIGN(size, getpagesize());
709
710 r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_VA, &va, sizeof(va));
711
712 return r;
713}
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
new file mode 100644
index 00000000..6747158c
--- /dev/null
+++ b/amdgpu/amdgpu_cs.c
@@ -0,0 +1,371 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <errno.h>
32#include <pthread.h>
33#include <sched.h>
34#include <sys/ioctl.h>
35#ifdef HAVE_ALLOCA_H
36# include <alloca.h>
37#endif
38
39#include "xf86drm.h"
40#include "amdgpu_drm.h"
41#include "amdgpu_internal.h"
42
43/**
44 * Create command submission context
45 *
46 * \param dev - \c [in] amdgpu device handle
47 * \param context - \c [out] amdgpu context handle
48 *
49 * \return 0 on success otherwise POSIX Error code
50*/
51int amdgpu_cs_ctx_create(amdgpu_device_handle dev,
52 amdgpu_context_handle *context)
53{
54 struct amdgpu_context *gpu_context;
55 union drm_amdgpu_ctx args;
56 int r;
57
58 if (NULL == dev)
59 return -EINVAL;
60 if (NULL == context)
61 return -EINVAL;
62
63 gpu_context = calloc(1, sizeof(struct amdgpu_context));
64 if (NULL == gpu_context)
65 return -ENOMEM;
66
67 gpu_context->dev = dev;
68
69 /* Create the context */
70 memset(&args, 0, sizeof(args));
71 args.in.op = AMDGPU_CTX_OP_ALLOC_CTX;
72 r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CTX, &args, sizeof(args));
73 if (r)
74 goto error;
75
76 gpu_context->id = args.out.alloc.ctx_id;
77 *context = (amdgpu_context_handle)gpu_context;
78
79 return 0;
80
81error:
82 free(gpu_context);
83 return r;
84}
85
86/**
87 * Release command submission context
88 *
89 * \param dev - \c [in] amdgpu device handle
90 * \param context - \c [in] amdgpu context handle
91 *
92 * \return 0 on success otherwise POSIX Error code
93*/
94int amdgpu_cs_ctx_free(amdgpu_context_handle context)
95{
96 union drm_amdgpu_ctx args;
97 int r;
98
99 if (NULL == context)
100 return -EINVAL;
101
102 /* now deal with kernel side */
103 memset(&args, 0, sizeof(args));
104 args.in.op = AMDGPU_CTX_OP_FREE_CTX;
105 args.in.ctx_id = context->id;
106 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX,
107 &args, sizeof(args));
108
109 free(context);
110
111 return r;
112}
113
114int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
115 uint32_t *state, uint32_t *hangs)
116{
117 union drm_amdgpu_ctx args;
118 int r;
119
120 if (!context)
121 return -EINVAL;
122
123 memset(&args, 0, sizeof(args));
124 args.in.op = AMDGPU_CTX_OP_QUERY_STATE;
125 args.in.ctx_id = context->id;
126 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX,
127 &args, sizeof(args));
128 if (!r) {
129 *state = args.out.state.reset_status;
130 *hangs = args.out.state.hangs;
131 }
132 return r;
133}
134
135/**
136 * Submit command to kernel DRM
137 * \param dev - \c [in] Device handle
138 * \param context - \c [in] GPU Context
139 * \param ibs_request - \c [in] Pointer to submission requests
140 * \param fence - \c [out] return fence for this submission
141 *
142 * \return 0 on success otherwise POSIX Error code
143 * \sa amdgpu_cs_submit()
144*/
145static int amdgpu_cs_submit_one(amdgpu_context_handle context,
146 struct amdgpu_cs_request *ibs_request)
147{
148 union drm_amdgpu_cs cs;
149 uint64_t *chunk_array;
150 struct drm_amdgpu_cs_chunk *chunks;
151 struct drm_amdgpu_cs_chunk_data *chunk_data;
152 struct drm_amdgpu_cs_chunk_dep *dependencies = NULL;
153 uint32_t i, size;
154 bool user_fence;
155 int r = 0;
156
157 if (ibs_request->ip_type >= AMDGPU_HW_IP_NUM)
158 return -EINVAL;
159 if (ibs_request->ring >= AMDGPU_CS_MAX_RINGS)
160 return -EINVAL;
161 if (ibs_request->number_of_ibs > AMDGPU_CS_MAX_IBS_PER_SUBMIT)
162 return -EINVAL;
163 user_fence = (ibs_request->fence_info.handle != NULL);
164
165 size = ibs_request->number_of_ibs + (user_fence ? 2 : 1);
166
167 chunk_array = alloca(sizeof(uint64_t) * size);
168 chunks = alloca(sizeof(struct drm_amdgpu_cs_chunk) * size);
169
170 size = ibs_request->number_of_ibs + (user_fence ? 1 : 0);
171
172 chunk_data = alloca(sizeof(struct drm_amdgpu_cs_chunk_data) * size);
173
174 memset(&cs, 0, sizeof(cs));
175 cs.in.chunks = (uint64_t)(uintptr_t)chunk_array;
176 cs.in.ctx_id = context->id;
177 if (ibs_request->resources)
178 cs.in.bo_list_handle = ibs_request->resources->handle;
179 cs.in.num_chunks = ibs_request->number_of_ibs;
180 /* IB chunks */
181 for (i = 0; i < ibs_request->number_of_ibs; i++) {
182 struct amdgpu_cs_ib_info *ib;
183 chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
184 chunks[i].chunk_id = AMDGPU_CHUNK_ID_IB;
185 chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
186 chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i];
187
188 ib = &ibs_request->ibs[i];
189
190 chunk_data[i].ib_data._pad = 0;
191 chunk_data[i].ib_data.va_start = ib->ib_mc_address;
192 chunk_data[i].ib_data.ib_bytes = ib->size * 4;
193 chunk_data[i].ib_data.ip_type = ibs_request->ip_type;
194 chunk_data[i].ib_data.ip_instance = ibs_request->ip_instance;
195 chunk_data[i].ib_data.ring = ibs_request->ring;
196 chunk_data[i].ib_data.flags = ib->flags;
197 }
198
199 if (user_fence) {
200 i = cs.in.num_chunks++;
201
202 /* fence chunk */
203 chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
204 chunks[i].chunk_id = AMDGPU_CHUNK_ID_FENCE;
205 chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_fence) / 4;
206 chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i];
207
208 /* fence bo handle */
209 chunk_data[i].fence_data.handle = ibs_request->fence_info.handle->handle;
210 /* offset */
211 chunk_data[i].fence_data.offset =
212 ibs_request->fence_info.offset * sizeof(uint64_t);
213 }
214
215 if (ibs_request->number_of_dependencies) {
216 dependencies = malloc(sizeof(struct drm_amdgpu_cs_chunk_dep) *
217 ibs_request->number_of_dependencies);
218 if (!dependencies) {
219 r = -ENOMEM;
220 goto error_unlock;
221 }
222
223 for (i = 0; i < ibs_request->number_of_dependencies; ++i) {
224 struct amdgpu_cs_fence *info = &ibs_request->dependencies[i];
225 struct drm_amdgpu_cs_chunk_dep *dep = &dependencies[i];
226 dep->ip_type = info->ip_type;
227 dep->ip_instance = info->ip_instance;
228 dep->ring = info->ring;
229 dep->ctx_id = info->context->id;
230 dep->handle = info->fence;
231 }
232
233 i = cs.in.num_chunks++;
234
235 /* dependencies chunk */
236 chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
237 chunks[i].chunk_id = AMDGPU_CHUNK_ID_DEPENDENCIES;
238 chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_dep) / 4
239 * ibs_request->number_of_dependencies;
240 chunks[i].chunk_data = (uint64_t)(uintptr_t)dependencies;
241 }
242
243 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CS,
244 &cs, sizeof(cs));
245 if (r)
246 goto error_unlock;
247
248 ibs_request->seq_no = cs.out.handle;
249
250error_unlock:
251 free(dependencies);
252 return r;
253}
254
255int amdgpu_cs_submit(amdgpu_context_handle context,
256 uint64_t flags,
257 struct amdgpu_cs_request *ibs_request,
258 uint32_t number_of_requests)
259{
260 uint32_t i;
261 int r;
262
263 if (NULL == context)
264 return -EINVAL;
265 if (NULL == ibs_request)
266 return -EINVAL;
267
268 r = 0;
269 for (i = 0; i < number_of_requests; i++) {
270 r = amdgpu_cs_submit_one(context, ibs_request);
271 if (r)
272 break;
273 ibs_request++;
274 }
275
276 return r;
277}
278
279/**
280 * Calculate absolute timeout.
281 *
282 * \param timeout - \c [in] timeout in nanoseconds.
283 *
284 * \return absolute timeout in nanoseconds
285*/
286drm_private uint64_t amdgpu_cs_calculate_timeout(uint64_t timeout)
287{
288 int r;
289
290 if (timeout != AMDGPU_TIMEOUT_INFINITE) {
291 struct timespec current;
292 uint64_t current_ns;
293 r = clock_gettime(CLOCK_MONOTONIC, &current);
294 if (r) {
295 fprintf(stderr, "clock_gettime() returned error (%d)!", errno);
296 return AMDGPU_TIMEOUT_INFINITE;
297 }
298
299 current_ns = ((uint64_t)current.tv_sec) * 1000000000ull;
300 current_ns += current.tv_nsec;
301 timeout += current_ns;
302 if (timeout < current_ns)
303 timeout = AMDGPU_TIMEOUT_INFINITE;
304 }
305 return timeout;
306}
307
308static int amdgpu_ioctl_wait_cs(amdgpu_context_handle context,
309 unsigned ip,
310 unsigned ip_instance,
311 uint32_t ring,
312 uint64_t handle,
313 uint64_t timeout_ns,
314 uint64_t flags,
315 bool *busy)
316{
317 amdgpu_device_handle dev = context->dev;
318 union drm_amdgpu_wait_cs args;
319 int r;
320
321 memset(&args, 0, sizeof(args));
322 args.in.handle = handle;
323 args.in.ip_type = ip;
324 args.in.ip_instance = ip_instance;
325 args.in.ring = ring;
326 args.in.ctx_id = context->id;
327
328 if (flags & AMDGPU_QUERY_FENCE_TIMEOUT_IS_ABSOLUTE)
329 args.in.timeout = timeout_ns;
330 else
331 args.in.timeout = amdgpu_cs_calculate_timeout(timeout_ns);
332
333 r = drmIoctl(dev->fd, DRM_IOCTL_AMDGPU_WAIT_CS, &args);
334 if (r)
335 return -errno;
336
337 *busy = args.out.status;
338 return 0;
339}
340
341int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence,
342 uint64_t timeout_ns,
343 uint64_t flags,
344 uint32_t *expired)
345{
346 bool busy = true;
347 int r;
348
349 if (NULL == fence)
350 return -EINVAL;
351 if (NULL == expired)
352 return -EINVAL;
353 if (NULL == fence->context)
354 return -EINVAL;
355 if (fence->ip_type >= AMDGPU_HW_IP_NUM)
356 return -EINVAL;
357 if (fence->ring >= AMDGPU_CS_MAX_RINGS)
358 return -EINVAL;
359
360 *expired = false;
361
362 r = amdgpu_ioctl_wait_cs(fence->context, fence->ip_type,
363 fence->ip_instance, fence->ring,
364 fence->fence, timeout_ns, flags, &busy);
365
366 if (!r && !busy)
367 *expired = true;
368
369 return r;
370}
371
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
new file mode 100644
index 00000000..e5a923e6
--- /dev/null
+++ b/amdgpu/amdgpu_device.c
@@ -0,0 +1,305 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24/**
25 * \file amdgpu_device.c
26 *
27 * Implementation of functions for AMD GPU device
28 *
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include <sys/stat.h>
36#include <errno.h>
37#include <string.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <unistd.h>
41
42#include "xf86drm.h"
43#include "amdgpu_drm.h"
44#include "amdgpu_internal.h"
45#include "util_hash_table.h"
46#include "util_math.h"
47
48#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
49#define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
50
51static pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER;
52static struct util_hash_table *fd_tab;
53
54static unsigned handle_hash(void *key)
55{
56 return PTR_TO_UINT(key);
57}
58
59static int handle_compare(void *key1, void *key2)
60{
61 return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
62}
63
64static unsigned fd_hash(void *key)
65{
66 int fd = PTR_TO_UINT(key);
67 char *name = drmGetPrimaryDeviceNameFromFd(fd);
68 unsigned result = 0;
69 char *c;
70
71 if (name == NULL)
72 return 0;
73
74 for (c = name; *c; ++c)
75 result += *c;
76
77 free(name);
78
79 return result;
80}
81
82static int fd_compare(void *key1, void *key2)
83{
84 int fd1 = PTR_TO_UINT(key1);
85 int fd2 = PTR_TO_UINT(key2);
86 char *name1 = drmGetPrimaryDeviceNameFromFd(fd1);
87 char *name2 = drmGetPrimaryDeviceNameFromFd(fd2);
88 int result;
89
90 if (name1 == NULL || name2 == NULL) {
91 free(name1);
92 free(name2);
93 return 0;
94 }
95
96 result = strcmp(name1, name2);
97 free(name1);
98 free(name2);
99
100 return result;
101}
102
103/**
104* Get the authenticated form fd,
105*
106* \param fd - \c [in] File descriptor for AMD GPU device
107* \param auth - \c [out] Pointer to output the fd is authenticated or not
108* A render node fd, output auth = 0
109* A legacy fd, get the authenticated for compatibility root
110*
111* \return 0 on success\n
112* >0 - AMD specific error code\n
113* <0 - Negative POSIX Error code
114*/
115static int amdgpu_get_auth(int fd, int *auth)
116{
117 int r = 0;
118 drm_client_t client = {};
119
120 if (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER)
121 *auth = 0;
122 else {
123 client.idx = 0;
124 r = drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client);
125 if (!r)
126 *auth = client.auth;
127 }
128 return r;
129}
130
131static void amdgpu_device_free_internal(amdgpu_device_handle dev)
132{
133 amdgpu_vamgr_deinit(dev->vamgr);
134 free(dev->vamgr);
135 amdgpu_vamgr_deinit(dev->vamgr_32);
136 free(dev->vamgr_32);
137 util_hash_table_destroy(dev->bo_flink_names);
138 util_hash_table_destroy(dev->bo_handles);
139 pthread_mutex_destroy(&dev->bo_table_mutex);
140 util_hash_table_remove(fd_tab, UINT_TO_PTR(dev->fd));
141 close(dev->fd);
142 if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
143 close(dev->flink_fd);
144 free(dev);
145}
146
147/**
148 * Assignment between two amdgpu_device pointers with reference counting.
149 *
150 * Usage:
151 * struct amdgpu_device *dst = ... , *src = ...;
152 *
153 * dst = src;
154 * // No reference counting. Only use this when you need to move
155 * // a reference from one pointer to another.
156 *
157 * amdgpu_device_reference(&dst, src);
158 * // Reference counters are updated. dst is decremented and src is
159 * // incremented. dst is freed if its reference counter is 0.
160 */
161static void amdgpu_device_reference(struct amdgpu_device **dst,
162 struct amdgpu_device *src)
163{
164 if (update_references(&(*dst)->refcount, &src->refcount))
165 amdgpu_device_free_internal(*dst);
166 *dst = src;
167}
168
169int amdgpu_device_initialize(int fd,
170 uint32_t *major_version,
171 uint32_t *minor_version,
172 amdgpu_device_handle *device_handle)
173{
174 struct amdgpu_device *dev;
175 drmVersionPtr version;
176 int r;
177 int flag_auth = 0;
178 int flag_authexist=0;
179 uint32_t accel_working = 0;
180 uint64_t start, max;
181
182 *device_handle = NULL;
183
184 pthread_mutex_lock(&fd_mutex);
185 if (!fd_tab)
186 fd_tab = util_hash_table_create(fd_hash, fd_compare);
187 r = amdgpu_get_auth(fd, &flag_auth);
188 if (r) {
189 pthread_mutex_unlock(&fd_mutex);
190 return r;
191 }
192 dev = util_hash_table_get(fd_tab, UINT_TO_PTR(fd));
193 if (dev) {
194 r = amdgpu_get_auth(dev->fd, &flag_authexist);
195 if (r) {
196 pthread_mutex_unlock(&fd_mutex);
197 return r;
198 }
199 if ((flag_auth) && (!flag_authexist)) {
200 dev->flink_fd = dup(fd);
201 }
202 *major_version = dev->major_version;
203 *minor_version = dev->minor_version;
204 amdgpu_device_reference(device_handle, dev);
205 pthread_mutex_unlock(&fd_mutex);
206 return 0;
207 }
208
209 dev = calloc(1, sizeof(struct amdgpu_device));
210 if (!dev) {
211 pthread_mutex_unlock(&fd_mutex);
212 return -ENOMEM;
213 }
214
215 dev->fd = -1;
216 dev->flink_fd = -1;
217
218 atomic_set(&dev->refcount, 1);
219
220 version = drmGetVersion(fd);
221 if (version->version_major != 3) {
222 fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
223 "only compatible with 3.x.x.\n",
224 __func__,
225 version->version_major,
226 version->version_minor,
227 version->version_patchlevel);
228 drmFreeVersion(version);
229 r = -EBADF;
230 goto cleanup;
231 }
232
233 dev->fd = dup(fd);
234 dev->flink_fd = dev->fd;
235 dev->major_version = version->version_major;
236 dev->minor_version = version->version_minor;
237 drmFreeVersion(version);
238
239 dev->bo_flink_names = util_hash_table_create(handle_hash,
240 handle_compare);
241 dev->bo_handles = util_hash_table_create(handle_hash, handle_compare);
242 pthread_mutex_init(&dev->bo_table_mutex, NULL);
243
244 /* Check if acceleration is working. */
245 r = amdgpu_query_info(dev, AMDGPU_INFO_ACCEL_WORKING, 4, &accel_working);
246 if (r)
247 goto cleanup;
248 if (!accel_working) {
249 r = -EBADF;
250 goto cleanup;
251 }
252
253 r = amdgpu_query_gpu_info_init(dev);
254 if (r)
255 goto cleanup;
256
257 dev->vamgr = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
258 if (dev->vamgr == NULL)
259 goto cleanup;
260
261 amdgpu_vamgr_init(dev->vamgr, dev->dev_info.virtual_address_offset,
262 dev->dev_info.virtual_address_max,
263 dev->dev_info.virtual_address_alignment);
264
265 max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff);
266 start = amdgpu_vamgr_find_va(dev->vamgr,
267 max - dev->dev_info.virtual_address_offset,
268 dev->dev_info.virtual_address_alignment, 0);
269 if (start > 0xffffffff)
270 goto free_va; /* shouldn't get here */
271
272 dev->vamgr_32 = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
273 if (dev->vamgr_32 == NULL)
274 goto free_va;
275 amdgpu_vamgr_init(dev->vamgr_32, start, max,
276 dev->dev_info.virtual_address_alignment);
277
278 *major_version = dev->major_version;
279 *minor_version = dev->minor_version;
280 *device_handle = dev;
281 util_hash_table_set(fd_tab, UINT_TO_PTR(dev->fd), dev);
282 pthread_mutex_unlock(&fd_mutex);
283
284 return 0;
285
286free_va:
287 r = -ENOMEM;
288 amdgpu_vamgr_free_va(dev->vamgr, start,
289 max - dev->dev_info.virtual_address_offset);
290 amdgpu_vamgr_deinit(dev->vamgr);
291 free(dev->vamgr);
292
293cleanup:
294 if (dev->fd >= 0)
295 close(dev->fd);
296 free(dev);
297 pthread_mutex_unlock(&fd_mutex);
298 return r;
299}
300
301int amdgpu_device_deinitialize(amdgpu_device_handle dev)
302{
303 amdgpu_device_reference(&dev, NULL);
304 return 0;
305}
diff --git a/amdgpu/amdgpu_gpu_info.c b/amdgpu/amdgpu_gpu_info.c
new file mode 100644
index 00000000..0cc17f1f
--- /dev/null
+++ b/amdgpu/amdgpu_gpu_info.c
@@ -0,0 +1,310 @@
1/*
2 * Copyright © 2014 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <errno.h>
30#include <string.h>
31
32#include "amdgpu.h"
33#include "amdgpu_drm.h"
34#include "amdgpu_internal.h"
35#include "xf86drm.h"
36
37int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
38 unsigned size, void *value)
39{
40 struct drm_amdgpu_info request;
41
42 memset(&request, 0, sizeof(request));
43 request.return_pointer = (uintptr_t)value;
44 request.return_size = size;
45 request.query = info_id;
46
47 return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
48 sizeof(struct drm_amdgpu_info));
49}
50
51int amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id,
52 int32_t *result)
53{
54 struct drm_amdgpu_info request;
55
56 memset(&request, 0, sizeof(request));
57 request.return_pointer = (uintptr_t)result;
58 request.return_size = sizeof(*result);
59 request.query = AMDGPU_INFO_CRTC_FROM_ID;
60 request.mode_crtc.id = id;
61
62 return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
63 sizeof(struct drm_amdgpu_info));
64}
65
66int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset,
67 unsigned count, uint32_t instance, uint32_t flags,
68 uint32_t *values)
69{
70 struct drm_amdgpu_info request;
71
72 memset(&request, 0, sizeof(request));
73 request.return_pointer = (uintptr_t)values;
74 request.return_size = count * sizeof(uint32_t);
75 request.query = AMDGPU_INFO_READ_MMR_REG;
76 request.read_mmr_reg.dword_offset = dword_offset;
77 request.read_mmr_reg.count = count;
78 request.read_mmr_reg.instance = instance;
79 request.read_mmr_reg.flags = flags;
80
81 return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
82 sizeof(struct drm_amdgpu_info));
83}
84
85int amdgpu_query_hw_ip_count(amdgpu_device_handle dev, unsigned type,
86 uint32_t *count)
87{
88 struct drm_amdgpu_info request;
89
90 memset(&request, 0, sizeof(request));
91 request.return_pointer = (uintptr_t)count;
92 request.return_size = sizeof(*count);
93 request.query = AMDGPU_INFO_HW_IP_COUNT;
94 request.query_hw_ip.type = type;
95
96 return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
97 sizeof(struct drm_amdgpu_info));
98}
99
100int amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type,
101 unsigned ip_instance,
102 struct drm_amdgpu_info_hw_ip *info)
103{
104 struct drm_amdgpu_info request;
105
106 memset(&request, 0, sizeof(request));
107 request.return_pointer = (uintptr_t)info;
108 request.return_size = sizeof(*info);
109 request.query = AMDGPU_INFO_HW_IP_INFO;
110 request.query_hw_ip.type = type;
111 request.query_hw_ip.ip_instance = ip_instance;
112
113 return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
114 sizeof(struct drm_amdgpu_info));
115}
116
117int amdgpu_query_firmware_version(amdgpu_device_handle dev, unsigned fw_type,
118 unsigned ip_instance, unsigned index,
119 uint32_t *version, uint32_t *feature)
120{
121 struct drm_amdgpu_info request;
122 struct drm_amdgpu_info_firmware firmware;
123 int r;
124
125 memset(&request, 0, sizeof(request));
126 request.return_pointer = (uintptr_t)&firmware;
127 request.return_size = sizeof(firmware);
128 request.query = AMDGPU_INFO_FW_VERSION;
129 request.query_fw.fw_type = fw_type;
130 request.query_fw.ip_instance = ip_instance;
131 request.query_fw.index = index;
132
133 r = drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
134 sizeof(struct drm_amdgpu_info));
135 if (r)
136 return r;
137
138 *version = firmware.ver;
139 *feature = firmware.feature;
140 return 0;
141}
142
143drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
144{
145 int r, i;
146
147 r = amdgpu_query_info(dev, AMDGPU_INFO_DEV_INFO, sizeof(dev->dev_info),
148 &dev->dev_info);
149 if (r)
150 return r;
151
152 dev->info.asic_id = dev->dev_info.device_id;
153 dev->info.chip_rev = dev->dev_info.chip_rev;
154 dev->info.chip_external_rev = dev->dev_info.external_rev;
155 dev->info.family_id = dev->dev_info.family;
156 dev->info.max_engine_clk = dev->dev_info.max_engine_clock;
157 dev->info.max_memory_clk = dev->dev_info.max_memory_clock;
158 dev->info.gpu_counter_freq = dev->dev_info.gpu_counter_freq;
159 dev->info.enabled_rb_pipes_mask = dev->dev_info.enabled_rb_pipes_mask;
160 dev->info.rb_pipes = dev->dev_info.num_rb_pipes;
161 dev->info.ids_flags = dev->dev_info.ids_flags;
162 dev->info.num_hw_gfx_contexts = dev->dev_info.num_hw_gfx_contexts;
163 dev->info.num_shader_engines = dev->dev_info.num_shader_engines;
164 dev->info.num_shader_arrays_per_engine =
165 dev->dev_info.num_shader_arrays_per_engine;
166 dev->info.vram_type = dev->dev_info.vram_type;
167 dev->info.vram_bit_width = dev->dev_info.vram_bit_width;
168 dev->info.ce_ram_size = dev->dev_info.ce_ram_size;
169 dev->info.vce_harvest_config = dev->dev_info.vce_harvest_config;
170 dev->info.pci_rev_id = dev->dev_info.pci_rev;
171
172 for (i = 0; i < (int)dev->info.num_shader_engines; i++) {
173 unsigned instance = (i << AMDGPU_INFO_MMR_SE_INDEX_SHIFT) |
174 (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
175 AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
176
177 r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
178 &dev->info.backend_disable[i]);
179 if (r)
180 return r;
181 /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */
182 dev->info.backend_disable[i] =
183 (dev->info.backend_disable[i] >> 16) & 0xff;
184
185 r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
186 &dev->info.pa_sc_raster_cfg[i]);
187 if (r)
188 return r;
189
190 r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
191 &dev->info.pa_sc_raster_cfg1[i]);
192 if (r)
193 return r;
194 }
195
196 r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
197 dev->info.gb_tile_mode);
198 if (r)
199 return r;
200
201 r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
202 dev->info.gb_macro_tile_mode);
203 if (r)
204 return r;
205
206 r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
207 &dev->info.gb_addr_cfg);
208 if (r)
209 return r;
210
211 r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
212 &dev->info.mc_arb_ramcfg);
213 if (r)
214 return r;
215
216 dev->info.cu_active_number = dev->dev_info.cu_active_number;
217 dev->info.cu_ao_mask = dev->dev_info.cu_ao_mask;
218 memcpy(&dev->info.cu_bitmap[0][0], &dev->dev_info.cu_bitmap[0][0], sizeof(dev->info.cu_bitmap));
219
220 /* TODO: info->max_quad_shader_pipes is not set */
221 /* TODO: info->avail_quad_shader_pipes is not set */
222 /* TODO: info->cache_entries_per_quad_pipe is not set */
223 return 0;
224}
225
226int amdgpu_query_gpu_info(amdgpu_device_handle dev,
227 struct amdgpu_gpu_info *info)
228{
229 /* Get ASIC info*/
230 *info = dev->info;
231
232 return 0;
233}
234
235int amdgpu_query_heap_info(amdgpu_device_handle dev,
236 uint32_t heap,
237 uint32_t flags,
238 struct amdgpu_heap_info *info)
239{
240 struct drm_amdgpu_info_vram_gtt vram_gtt_info = {};
241 int r;
242
243 r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_GTT,
244 sizeof(vram_gtt_info), &vram_gtt_info);
245 if (r)
246 return r;
247
248 /* Get heap information */
249 switch (heap) {
250 case AMDGPU_GEM_DOMAIN_VRAM:
251 /* query visible only vram heap */
252 if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
253 info->heap_size = vram_gtt_info.vram_cpu_accessible_size;
254 else /* query total vram heap */
255 info->heap_size = vram_gtt_info.vram_size;
256
257 info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
258
259 if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
260 r = amdgpu_query_info(dev, AMDGPU_INFO_VIS_VRAM_USAGE,
261 sizeof(info->heap_usage),
262 &info->heap_usage);
263 else
264 r = amdgpu_query_info(dev, AMDGPU_INFO_VRAM_USAGE,
265 sizeof(info->heap_usage),
266 &info->heap_usage);
267 if (r)
268 return r;
269 break;
270 case AMDGPU_GEM_DOMAIN_GTT:
271 info->heap_size = vram_gtt_info.gtt_size;
272 info->max_allocation = vram_gtt_info.vram_cpu_accessible_size;
273
274 r = amdgpu_query_info(dev, AMDGPU_INFO_GTT_USAGE,
275 sizeof(info->heap_usage),
276 &info->heap_usage);
277 if (r)
278 return r;
279 break;
280 default:
281 return -EINVAL;
282 }
283
284 return 0;
285}
286
287int amdgpu_query_gds_info(amdgpu_device_handle dev,
288 struct amdgpu_gds_resource_info *gds_info)
289{
290 struct drm_amdgpu_info_gds gds_config = {};
291 int r;
292
293 if (gds_info == NULL)
294 return -EINVAL;
295
296 r = amdgpu_query_info(dev, AMDGPU_INFO_GDS_CONFIG,
297 sizeof(gds_config), &gds_config);
298 if (r)
299 return r;
300
301 gds_info->gds_gfx_partition_size = gds_config.gds_gfx_partition_size;
302 gds_info->compute_partition_size = gds_config.compute_partition_size;
303 gds_info->gds_total_size = gds_config.gds_total_size;
304 gds_info->gws_per_gfx_partition = gds_config.gws_per_gfx_partition;
305 gds_info->gws_per_compute_partition = gds_config.gws_per_compute_partition;
306 gds_info->oa_per_gfx_partition = gds_config.oa_per_gfx_partition;
307 gds_info->oa_per_compute_partition = gds_config.oa_per_compute_partition;
308
309 return 0;
310}
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
new file mode 100644
index 00000000..7dd5c1c7
--- /dev/null
+++ b/amdgpu/amdgpu_internal.h
@@ -0,0 +1,188 @@
1/*
2 * Copyright © 2014 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25#ifndef _AMDGPU_INTERNAL_H_
26#define _AMDGPU_INTERNAL_H_
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <assert.h>
33#include <pthread.h>
34
35#include "libdrm_macros.h"
36#include "xf86atomic.h"
37#include "amdgpu.h"
38#include "util_double_list.h"
39
40#define AMDGPU_CS_MAX_RINGS 8
41/* do not use below macro if b is not power of 2 aligned value */
42#define __round_mask(x, y) ((__typeof__(x))((y)-1))
43#define ROUND_UP(x, y) ((((x)-1) | __round_mask(x, y))+1)
44#define ROUND_DOWN(x, y) ((x) & ~__round_mask(x, y))
45
46#define AMDGPU_INVALID_VA_ADDRESS 0xffffffffffffffff
47
48struct amdgpu_bo_va_hole {
49 struct list_head list;
50 uint64_t offset;
51 uint64_t size;
52};
53
54struct amdgpu_bo_va_mgr {
55 /* the start virtual address */
56 uint64_t va_offset;
57 uint64_t va_max;
58 struct list_head va_holes;
59 pthread_mutex_t bo_va_mutex;
60 uint32_t va_alignment;
61};
62
63struct amdgpu_va {
64 amdgpu_device_handle dev;
65 uint64_t address;
66 uint64_t size;
67 enum amdgpu_gpu_va_range range;
68 struct amdgpu_bo_va_mgr *vamgr;
69};
70
71struct amdgpu_device {
72 atomic_t refcount;
73 int fd;
74 int flink_fd;
75 unsigned major_version;
76 unsigned minor_version;
77
78 /** List of buffer handles. Protected by bo_table_mutex. */
79 struct util_hash_table *bo_handles;
80 /** List of buffer GEM flink names. Protected by bo_table_mutex. */
81 struct util_hash_table *bo_flink_names;
82 /** This protects all hash tables. */
83 pthread_mutex_t bo_table_mutex;
84 struct drm_amdgpu_info_device dev_info;
85 struct amdgpu_gpu_info info;
86 /** The global VA manager for the whole virtual address space */
87 struct amdgpu_bo_va_mgr *vamgr;
88 /** The VA manager for the 32bit address space */
89 struct amdgpu_bo_va_mgr *vamgr_32;
90};
91
92struct amdgpu_bo {
93 atomic_t refcount;
94 struct amdgpu_device *dev;
95
96 uint64_t alloc_size;
97
98 uint32_t handle;
99 uint32_t flink_name;
100
101 pthread_mutex_t cpu_access_mutex;
102 void *cpu_ptr;
103 int cpu_map_count;
104};
105
106struct amdgpu_bo_list {
107 struct amdgpu_device *dev;
108
109 uint32_t handle;
110};
111
112struct amdgpu_context {
113 struct amdgpu_device *dev;
114 /* context id*/
115 uint32_t id;
116};
117
118/**
119 * Functions.
120 */
121
122drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo);
123
124drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
125 uint64_t max, uint64_t alignment);
126
127drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
128
129drm_private uint64_t
130amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
131 uint64_t alignment, uint64_t base_required);
132
133drm_private void
134amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va, uint64_t size);
135
136drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev);
137
138drm_private uint64_t amdgpu_cs_calculate_timeout(uint64_t timeout);
139
140/**
141 * Inline functions.
142 */
143
144/**
145 * Increment src and decrement dst as if we were updating references
146 * for an assignment between 2 pointers of some objects.
147 *
148 * \return true if dst is 0
149 */
150static inline bool update_references(atomic_t *dst, atomic_t *src)
151{
152 if (dst != src) {
153 /* bump src first */
154 if (src) {
155 assert(atomic_read(src) > 0);
156 atomic_inc(src);
157 }
158 if (dst) {
159 assert(atomic_read(dst) > 0);
160 return atomic_dec_and_test(dst);
161 }
162 }
163 return false;
164}
165
166/**
167 * Assignment between two amdgpu_bo pointers with reference counting.
168 *
169 * Usage:
170 * struct amdgpu_bo *dst = ... , *src = ...;
171 *
172 * dst = src;
173 * // No reference counting. Only use this when you need to move
174 * // a reference from one pointer to another.
175 *
176 * amdgpu_bo_reference(&dst, src);
177 * // Reference counters are updated. dst is decremented and src is
178 * // incremented. dst is freed if its reference counter is 0.
179 */
180static inline void amdgpu_bo_reference(struct amdgpu_bo **dst,
181 struct amdgpu_bo *src)
182{
183 if (update_references(&(*dst)->refcount, &src->refcount))
184 amdgpu_bo_free_internal(*dst);
185 *dst = src;
186}
187
188#endif
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
new file mode 100644
index 00000000..8a707cbc
--- /dev/null
+++ b/amdgpu/amdgpu_vamgr.c
@@ -0,0 +1,287 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <stdlib.h>
29#include <string.h>
30#include <errno.h>
31#include "amdgpu.h"
32#include "amdgpu_drm.h"
33#include "amdgpu_internal.h"
34#include "util_math.h"
35
36int amdgpu_va_range_query(amdgpu_device_handle dev,
37 enum amdgpu_gpu_va_range type, uint64_t *start, uint64_t *end)
38{
39 if (type == amdgpu_gpu_va_range_general) {
40 *start = dev->dev_info.virtual_address_offset;
41 *end = dev->dev_info.virtual_address_max;
42 return 0;
43 }
44 return -EINVAL;
45}
46
47drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
48 uint64_t max, uint64_t alignment)
49{
50 mgr->va_offset = start;
51 mgr->va_max = max;
52 mgr->va_alignment = alignment;
53
54 list_inithead(&mgr->va_holes);
55 pthread_mutex_init(&mgr->bo_va_mutex, NULL);
56}
57
58drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
59{
60 struct amdgpu_bo_va_hole *hole, *tmp;
61 LIST_FOR_EACH_ENTRY_SAFE(hole, tmp, &mgr->va_holes, list) {
62 list_del(&hole->list);
63 free(hole);
64 }
65 pthread_mutex_destroy(&mgr->bo_va_mutex);
66}
67
68drm_private uint64_t
69amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
70 uint64_t alignment, uint64_t base_required)
71{
72 struct amdgpu_bo_va_hole *hole, *n;
73 uint64_t offset = 0, waste = 0;
74
75 alignment = MAX2(alignment, mgr->va_alignment);
76 size = ALIGN(size, mgr->va_alignment);
77
78 if (base_required % alignment)
79 return AMDGPU_INVALID_VA_ADDRESS;
80
81 pthread_mutex_lock(&mgr->bo_va_mutex);
82 /* TODO: using more appropriate way to track the holes */
83 /* first look for a hole */
84 LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) {
85 if (base_required) {
86 if(hole->offset > base_required ||
87 (hole->offset + hole->size) < (base_required + size))
88 continue;
89 waste = base_required - hole->offset;
90 offset = base_required;
91 } else {
92 offset = hole->offset;
93 waste = offset % alignment;
94 waste = waste ? alignment - waste : 0;
95 offset += waste;
96 if (offset >= (hole->offset + hole->size)) {
97 continue;
98 }
99 }
100 if (!waste && hole->size == size) {
101 offset = hole->offset;
102 list_del(&hole->list);
103 free(hole);
104 pthread_mutex_unlock(&mgr->bo_va_mutex);
105 return offset;
106 }
107 if ((hole->size - waste) > size) {
108 if (waste) {
109 n = calloc(1, sizeof(struct amdgpu_bo_va_hole));
110 n->size = waste;
111 n->offset = hole->offset;
112 list_add(&n->list, &hole->list);
113 }
114 hole->size -= (size + waste);
115 hole->offset += size + waste;
116 pthread_mutex_unlock(&mgr->bo_va_mutex);
117 return offset;
118 }
119 if ((hole->size - waste) == size) {
120 hole->size = waste;
121 pthread_mutex_unlock(&mgr->bo_va_mutex);
122 return offset;
123 }
124 }
125
126 if (base_required) {
127 if (base_required < mgr->va_offset) {
128 pthread_mutex_unlock(&mgr->bo_va_mutex);
129 return AMDGPU_INVALID_VA_ADDRESS;
130 }
131 offset = mgr->va_offset;
132 waste = base_required - mgr->va_offset;
133 } else {
134 offset = mgr->va_offset;
135 waste = offset % alignment;
136 waste = waste ? alignment - waste : 0;
137 }
138
139 if (offset + waste + size > mgr->va_max) {
140 pthread_mutex_unlock(&mgr->bo_va_mutex);
141 return AMDGPU_INVALID_VA_ADDRESS;
142 }
143
144 if (waste) {
145 n = calloc(1, sizeof(struct amdgpu_bo_va_hole));
146 n->size = waste;
147 n->offset = offset;
148 list_add(&n->list, &mgr->va_holes);
149 }
150
151 offset += waste;
152 mgr->va_offset += size + waste;
153 pthread_mutex_unlock(&mgr->bo_va_mutex);
154 return offset;
155}
156
157drm_private void
158amdgpu_vamgr_free_va(struct amdgpu_bo_va_mgr *mgr, uint64_t va, uint64_t size)
159{
160 struct amdgpu_bo_va_hole *hole;
161
162 if (va == AMDGPU_INVALID_VA_ADDRESS)
163 return;
164
165 size = ALIGN(size, mgr->va_alignment);
166
167 pthread_mutex_lock(&mgr->bo_va_mutex);
168 if ((va + size) == mgr->va_offset) {
169 mgr->va_offset = va;
170 /* Delete uppermost hole if it reaches the new top */
171 if (!LIST_IS_EMPTY(&mgr->va_holes)) {
172 hole = container_of(mgr->va_holes.next, hole, list);
173 if ((hole->offset + hole->size) == va) {
174 mgr->va_offset = hole->offset;
175 list_del(&hole->list);
176 free(hole);
177 }
178 }
179 } else {
180 struct amdgpu_bo_va_hole *next;
181
182 hole = container_of(&mgr->va_holes, hole, list);
183 LIST_FOR_EACH_ENTRY(next, &mgr->va_holes, list) {
184 if (next->offset < va)
185 break;
186 hole = next;
187 }
188
189 if (&hole->list != &mgr->va_holes) {
190 /* Grow upper hole if it's adjacent */
191 if (hole->offset == (va + size)) {
192 hole->offset = va;
193 hole->size += size;
194 /* Merge lower hole if it's adjacent */
195 if (next != hole
196 && &next->list != &mgr->va_holes
197 && (next->offset + next->size) == va) {
198 next->size += hole->size;
199 list_del(&hole->list);
200 free(hole);
201 }
202 goto out;
203 }
204 }
205
206 /* Grow lower hole if it's adjacent */
207 if (next != hole && &next->list != &mgr->va_holes &&
208 (next->offset + next->size) == va) {
209 next->size += size;
210 goto out;
211 }
212
213 /* FIXME on allocation failure we just lose virtual address space
214 * maybe print a warning
215 */
216 next = calloc(1, sizeof(struct amdgpu_bo_va_hole));
217 if (next) {
218 next->size = size;
219 next->offset = va;
220 list_add(&next->list, &hole->list);
221 }
222 }
223out:
224 pthread_mutex_unlock(&mgr->bo_va_mutex);
225}
226
227int amdgpu_va_range_alloc(amdgpu_device_handle dev,
228 enum amdgpu_gpu_va_range va_range_type,
229 uint64_t size,
230 uint64_t va_base_alignment,
231 uint64_t va_base_required,
232 uint64_t *va_base_allocated,
233 amdgpu_va_handle *va_range_handle,
234 uint64_t flags)
235{
236 struct amdgpu_bo_va_mgr *vamgr;
237
238 if (flags & AMDGPU_VA_RANGE_32_BIT)
239 vamgr = dev->vamgr_32;
240 else
241 vamgr = dev->vamgr;
242
243 va_base_alignment = MAX2(va_base_alignment, vamgr->va_alignment);
244 size = ALIGN(size, vamgr->va_alignment);
245
246 *va_base_allocated = amdgpu_vamgr_find_va(vamgr, size,
247 va_base_alignment, va_base_required);
248
249 if (!(flags & AMDGPU_VA_RANGE_32_BIT) &&
250 (*va_base_allocated == AMDGPU_INVALID_VA_ADDRESS)) {
251 /* fallback to 32bit address */
252 vamgr = dev->vamgr_32;
253 *va_base_allocated = amdgpu_vamgr_find_va(vamgr, size,
254 va_base_alignment, va_base_required);
255 }
256
257 if (*va_base_allocated != AMDGPU_INVALID_VA_ADDRESS) {
258 struct amdgpu_va* va;
259 va = calloc(1, sizeof(struct amdgpu_va));
260 if(!va){
261 amdgpu_vamgr_free_va(vamgr, *va_base_allocated, size);
262 return -ENOMEM;
263 }
264 va->dev = dev;
265 va->address = *va_base_allocated;
266 va->size = size;
267 va->range = va_range_type;
268 va->vamgr = vamgr;
269 *va_range_handle = va;
270 } else {
271 return -EINVAL;
272 }
273
274 return 0;
275}
276
277int amdgpu_va_range_free(amdgpu_va_handle va_range_handle)
278{
279 if(!va_range_handle || !va_range_handle->address)
280 return 0;
281
282 amdgpu_vamgr_free_va(va_range_handle->vamgr,
283 va_range_handle->address,
284 va_range_handle->size);
285 free(va_range_handle);
286 return 0;
287}
diff --git a/amdgpu/libdrm_amdgpu.pc.in b/amdgpu/libdrm_amdgpu.pc.in
new file mode 100644
index 00000000..417865e5
--- /dev/null
+++ b/amdgpu/libdrm_amdgpu.pc.in
@@ -0,0 +1,10 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: libdrm_amdgpu
7Description: Userspace interface to kernel DRM services for amdgpu
8Version: @PACKAGE_VERSION@
9Libs: -L${libdir} -ldrm_amdgpu
10Cflags: -I${includedir} -I${includedir}/libdrm
diff --git a/amdgpu/util_hash.c b/amdgpu/util_hash.c
new file mode 100644
index 00000000..87cb671b
--- /dev/null
+++ b/amdgpu/util_hash.c
@@ -0,0 +1,387 @@
1/**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Zack Rusin <zackr@vmware.com>
31 */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include "util_hash.h"
38
39#include <stdlib.h>
40#include <assert.h>
41
42#define MAX(a, b) ((a > b) ? (a) : (b))
43
44static const int MinNumBits = 4;
45
46static const unsigned char prime_deltas[] = {
47 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
48 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
49};
50
51static int primeForNumBits(int numBits)
52{
53 return (1 << numBits) + prime_deltas[numBits];
54}
55
56/* Returns the smallest integer n such that
57 primeForNumBits(n) >= hint.
58*/
59static int countBits(int hint)
60{
61 int numBits = 0;
62 int bits = hint;
63
64 while (bits > 1) {
65 bits >>= 1;
66 numBits++;
67 }
68
69 if (numBits >= (int)sizeof(prime_deltas)) {
70 numBits = sizeof(prime_deltas) - 1;
71 } else if (primeForNumBits(numBits) < hint) {
72 ++numBits;
73 }
74 return numBits;
75}
76
77struct util_node {
78 struct util_node *next;
79 unsigned key;
80 void *value;
81};
82
83struct util_hash_data {
84 struct util_node *fakeNext;
85 struct util_node **buckets;
86 int size;
87 int nodeSize;
88 short userNumBits;
89 short numBits;
90 int numBuckets;
91};
92
93struct util_hash {
94 union {
95 struct util_hash_data *d;
96 struct util_node *e;
97 } data;
98};
99
100static void *util_data_allocate_node(struct util_hash_data *hash)
101{
102 return malloc(hash->nodeSize);
103}
104
105static void util_free_node(struct util_node *node)
106{
107 free(node);
108}
109
110static struct util_node *
111util_hash_create_node(struct util_hash *hash,
112 unsigned akey, void *avalue,
113 struct util_node **anextNode)
114{
115 struct util_node *node = util_data_allocate_node(hash->data.d);
116
117 if (!node)
118 return NULL;
119
120 node->key = akey;
121 node->value = avalue;
122
123 node->next = (struct util_node*)(*anextNode);
124 *anextNode = node;
125 ++hash->data.d->size;
126 return node;
127}
128
129static void util_data_rehash(struct util_hash_data *hash, int hint)
130{
131 if (hint < 0) {
132 hint = countBits(-hint);
133 if (hint < MinNumBits)
134 hint = MinNumBits;
135 hash->userNumBits = (short)hint;
136 while (primeForNumBits(hint) < (hash->size >> 1))
137 ++hint;
138 } else if (hint < MinNumBits) {
139 hint = MinNumBits;
140 }
141
142 if (hash->numBits != hint) {
143 struct util_node *e = (struct util_node *)(hash);
144 struct util_node **oldBuckets = hash->buckets;
145 int oldNumBuckets = hash->numBuckets;
146 int i = 0;
147
148 hash->numBits = (short)hint;
149 hash->numBuckets = primeForNumBits(hint);
150 hash->buckets = malloc(sizeof(struct util_node*) * hash->numBuckets);
151 for (i = 0; i < hash->numBuckets; ++i)
152 hash->buckets[i] = e;
153
154 for (i = 0; i < oldNumBuckets; ++i) {
155 struct util_node *firstNode = oldBuckets[i];
156 while (firstNode != e) {
157 unsigned h = firstNode->key;
158 struct util_node *lastNode = firstNode;
159 struct util_node *afterLastNode;
160 struct util_node **beforeFirstNode;
161
162 while (lastNode->next != e && lastNode->next->key == h)
163 lastNode = lastNode->next;
164
165 afterLastNode = lastNode->next;
166 beforeFirstNode = &hash->buckets[h % hash->numBuckets];
167 while (*beforeFirstNode != e)
168 beforeFirstNode = &(*beforeFirstNode)->next;
169 lastNode->next = *beforeFirstNode;
170 *beforeFirstNode = firstNode;
171 firstNode = afterLastNode;
172 }
173 }
174 free(oldBuckets);
175 }
176}
177
178static void util_data_might_grow(struct util_hash_data *hash)
179{
180 if (hash->size >= hash->numBuckets)
181 util_data_rehash(hash, hash->numBits + 1);
182}
183
184static void util_data_has_shrunk(struct util_hash_data *hash)
185{
186 if (hash->size <= (hash->numBuckets >> 3) &&
187 hash->numBits > hash->userNumBits) {
188 int max = MAX(hash->numBits-2, hash->userNumBits);
189 util_data_rehash(hash, max);
190 }
191}
192
193static struct util_node *util_data_first_node(struct util_hash_data *hash)
194{
195 struct util_node *e = (struct util_node *)(hash);
196 struct util_node **bucket = hash->buckets;
197 int n = hash->numBuckets;
198 while (n--) {
199 if (*bucket != e)
200 return *bucket;
201 ++bucket;
202 }
203 return e;
204}
205
206static struct util_node **util_hash_find_node(struct util_hash *hash, unsigned akey)
207{
208 struct util_node **node;
209
210 if (hash->data.d->numBuckets) {
211 node = (struct util_node **)(&hash->data.d->buckets[akey % hash->data.d->numBuckets]);
212 assert(*node == hash->data.e || (*node)->next);
213 while (*node != hash->data.e && (*node)->key != akey)
214 node = &(*node)->next;
215 } else {
216 node = (struct util_node **)((const struct util_node * const *)(&hash->data.e));
217 }
218 return node;
219}
220
221drm_private struct util_hash_iter
222util_hash_insert(struct util_hash *hash, unsigned key, void *data)
223{
224 util_data_might_grow(hash->data.d);
225
226 {
227 struct util_node **nextNode = util_hash_find_node(hash, key);
228 struct util_node *node = util_hash_create_node(hash, key, data, nextNode);
229 if (!node) {
230 struct util_hash_iter null_iter = {hash, 0};
231 return null_iter;
232 }
233
234 {
235 struct util_hash_iter iter = {hash, node};
236 return iter;
237 }
238 }
239}
240
241drm_private struct util_hash *util_hash_create(void)
242{
243 struct util_hash *hash = malloc(sizeof(struct util_hash));
244 if (!hash)
245 return NULL;
246
247 hash->data.d = malloc(sizeof(struct util_hash_data));
248 if (!hash->data.d) {
249 free(hash);
250 return NULL;
251 }
252
253 hash->data.d->fakeNext = 0;
254 hash->data.d->buckets = 0;
255 hash->data.d->size = 0;
256 hash->data.d->nodeSize = sizeof(struct util_node);
257 hash->data.d->userNumBits = (short)MinNumBits;
258 hash->data.d->numBits = 0;
259 hash->data.d->numBuckets = 0;
260
261 return hash;
262}
263
264drm_private void util_hash_delete(struct util_hash *hash)
265{
266 struct util_node *e_for_x = (struct util_node *)(hash->data.d);
267 struct util_node **bucket = (struct util_node **)(hash->data.d->buckets);
268 int n = hash->data.d->numBuckets;
269 while (n--) {
270 struct util_node *cur = *bucket++;
271 while (cur != e_for_x) {
272 struct util_node *next = cur->next;
273 util_free_node(cur);
274 cur = next;
275 }
276 }
277 free(hash->data.d->buckets);
278 free(hash->data.d);
279 free(hash);
280}
281
282drm_private struct util_hash_iter
283util_hash_find(struct util_hash *hash, unsigned key)
284{
285 struct util_node **nextNode = util_hash_find_node(hash, key);
286 struct util_hash_iter iter = {hash, *nextNode};
287 return iter;
288}
289
290drm_private unsigned util_hash_iter_key(struct util_hash_iter iter)
291{
292 if (!iter.node || iter.hash->data.e == iter.node)
293 return 0;
294 return iter.node->key;
295}
296
297drm_private void *util_hash_iter_data(struct util_hash_iter iter)
298{
299 if (!iter.node || iter.hash->data.e == iter.node)
300 return 0;
301 return iter.node->value;
302}
303
304static struct util_node *util_hash_data_next(struct util_node *node)
305{
306 union {
307 struct util_node *next;
308 struct util_node *e;
309 struct util_hash_data *d;
310 } a;
311 int start;
312 struct util_node **bucket;
313 int n;
314
315 a.next = node->next;
316 if (!a.next) {
317 /* iterating beyond the last element */
318 return 0;
319 }
320 if (a.next->next)
321 return a.next;
322
323 start = (node->key % a.d->numBuckets) + 1;
324 bucket = a.d->buckets + start;
325 n = a.d->numBuckets - start;
326 while (n--) {
327 if (*bucket != a.e)
328 return *bucket;
329 ++bucket;
330 }
331 return a.e;
332}
333
334drm_private struct util_hash_iter
335util_hash_iter_next(struct util_hash_iter iter)
336{
337 struct util_hash_iter next = {iter.hash, util_hash_data_next(iter.node)};
338 return next;
339}
340
341drm_private int util_hash_iter_is_null(struct util_hash_iter iter)
342{
343 if (!iter.node || iter.node == iter.hash->data.e)
344 return 1;
345 return 0;
346}
347
348drm_private void *util_hash_take(struct util_hash *hash, unsigned akey)
349{
350 struct util_node **node = util_hash_find_node(hash, akey);
351 if (*node != hash->data.e) {
352 void *t = (*node)->value;
353 struct util_node *next = (*node)->next;
354 util_free_node(*node);
355 *node = next;
356 --hash->data.d->size;
357 util_data_has_shrunk(hash->data.d);
358 return t;
359 }
360 return 0;
361}
362
363drm_private struct util_hash_iter util_hash_first_node(struct util_hash *hash)
364{
365 struct util_hash_iter iter = {hash, util_data_first_node(hash->data.d)};
366 return iter;
367}
368
369drm_private struct util_hash_iter
370util_hash_erase(struct util_hash *hash, struct util_hash_iter iter)
371{
372 struct util_hash_iter ret = iter;
373 struct util_node *node = iter.node;
374 struct util_node **node_ptr;
375
376 if (node == hash->data.e)
377 return iter;
378
379 ret = util_hash_iter_next(ret);
380 node_ptr = (struct util_node**)(&hash->data.d->buckets[node->key % hash->data.d->numBuckets]);
381 while (*node_ptr != node)
382 node_ptr = &(*node_ptr)->next;
383 *node_ptr = node->next;
384 util_free_node(node);
385 --hash->data.d->size;
386 return ret;
387}
diff --git a/amdgpu/util_hash.h b/amdgpu/util_hash.h
new file mode 100644
index 00000000..01a4779b
--- /dev/null
+++ b/amdgpu/util_hash.h
@@ -0,0 +1,107 @@
1/**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28/**
29 * @file
30 * Hash implementation.
31 *
32 * This file provides a hash implementation that is capable of dealing
33 * with collisions. It stores colliding entries in linked list. All
34 * functions operating on the hash return an iterator. The iterator
35 * itself points to the collision list. If there wasn't any collision
36 * the list will have just one entry, otherwise client code should
37 * iterate over the entries to find the exact entry among ones that
38 * had the same key (e.g. memcmp could be used on the data to check
39 * that)
40 *
41 * @author Zack Rusin <zackr@vmware.com>
42 */
43
44#ifndef UTIL_HASH_H
45#define UTIL_HASH_H
46
47#ifdef HAVE_CONFIG_H
48#include "config.h"
49#endif
50
51#include <stdbool.h>
52
53#include "libdrm_macros.h"
54
55struct util_hash;
56struct util_node;
57
58struct util_hash_iter {
59 struct util_hash *hash;
60 struct util_node *node;
61};
62
63
64drm_private struct util_hash *util_hash_create(void);
65drm_private void util_hash_delete(struct util_hash *hash);
66
67
68/**
69 * Adds a data with the given key to the hash. If entry with the given
70 * key is already in the hash, this current entry is instered before it
71 * in the collision list.
72 * Function returns iterator pointing to the inserted item in the hash.
73 */
74drm_private struct util_hash_iter
75util_hash_insert(struct util_hash *hash, unsigned key, void *data);
76
77/**
78 * Removes the item pointed to by the current iterator from the hash.
79 * Note that the data itself is not erased and if it was a malloc'ed pointer
80 * it will have to be freed after calling this function by the callee.
81 * Function returns iterator pointing to the item after the removed one in
82 * the hash.
83 */
84drm_private struct util_hash_iter
85util_hash_erase(struct util_hash *hash, struct util_hash_iter iter);
86
87drm_private void *util_hash_take(struct util_hash *hash, unsigned key);
88
89
90drm_private struct util_hash_iter util_hash_first_node(struct util_hash *hash);
91
92/**
93 * Return an iterator pointing to the first entry in the collision list.
94 */
95drm_private struct util_hash_iter
96util_hash_find(struct util_hash *hash, unsigned key);
97
98
99drm_private int util_hash_iter_is_null(struct util_hash_iter iter);
100drm_private unsigned util_hash_iter_key(struct util_hash_iter iter);
101drm_private void *util_hash_iter_data(struct util_hash_iter iter);
102
103
104drm_private struct util_hash_iter
105util_hash_iter_next(struct util_hash_iter iter);
106
107#endif
diff --git a/amdgpu/util_hash_table.c b/amdgpu/util_hash_table.c
new file mode 100644
index 00000000..fa7f6eab
--- /dev/null
+++ b/amdgpu/util_hash_table.c
@@ -0,0 +1,262 @@
1/**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28/**
29 * @file
30 * General purpose hash table implementation.
31 *
32 * Just uses the util_hash for now, but it might be better switch to a linear
33 * probing hash table implementation at some point -- as it is said they have
34 * better lookup and cache performance and it appears to be possible to write
35 * a lock-free implementation of such hash tables .
36 *
37 * @author José Fonseca <jfonseca@vmware.com>
38 */
39
40
41#ifdef HAVE_CONFIG_H
42#include "config.h"
43#endif
44
45#include "util_hash_table.h"
46#include "util_hash.h"
47
48#include <stdlib.h>
49#include <assert.h>
50
51struct util_hash_table
52{
53 struct util_hash *head;
54
55 /** Hash function */
56 unsigned (*make_hash)(void *key);
57
58 /** Compare two keys */
59 int (*compare)(void *key1, void *key2);
60};
61
62struct util_hash_table_item
63{
64 void *key;
65 void *value;
66};
67
68
69static struct util_hash_table_item *
70util_hash_table_item(struct util_hash_iter iter)
71{
72 return (struct util_hash_table_item *)util_hash_iter_data(iter);
73}
74
75drm_private struct util_hash_table *
76util_hash_table_create(unsigned (*hash)(void *key),
77 int (*compare)(void *key1, void *key2))
78{
79 struct util_hash_table *ht;
80
81 ht = malloc(sizeof(struct util_hash_table));
82 if(!ht)
83 return NULL;
84
85 ht->head = util_hash_create();
86 if(!ht->head) {
87 free(ht);
88 return NULL;
89 }
90
91 ht->make_hash = hash;
92 ht->compare = compare;
93
94 return ht;
95}
96
97static struct util_hash_iter
98util_hash_table_find_iter(struct util_hash_table *ht,
99 void *key, unsigned key_hash)
100{
101 struct util_hash_iter iter;
102 struct util_hash_table_item *item;
103
104 iter = util_hash_find(ht->head, key_hash);
105 while (!util_hash_iter_is_null(iter)) {
106 item = (struct util_hash_table_item *)util_hash_iter_data(iter);
107 if (!ht->compare(item->key, key))
108 break;
109 iter = util_hash_iter_next(iter);
110 }
111
112 return iter;
113}
114
115static struct util_hash_table_item *
116util_hash_table_find_item(struct util_hash_table *ht,
117 void *key, unsigned key_hash)
118{
119 struct util_hash_iter iter;
120 struct util_hash_table_item *item;
121
122 iter = util_hash_find(ht->head, key_hash);
123 while (!util_hash_iter_is_null(iter)) {
124 item = (struct util_hash_table_item *)util_hash_iter_data(iter);
125 if (!ht->compare(item->key, key))
126 return item;
127 iter = util_hash_iter_next(iter);
128 }
129
130 return NULL;
131}
132
133drm_private void
134util_hash_table_set(struct util_hash_table *ht, void *key, void *value)
135{
136 unsigned key_hash;
137 struct util_hash_table_item *item;
138 struct util_hash_iter iter;
139
140 assert(ht);
141 if (!ht)
142 return;
143
144 key_hash = ht->make_hash(key);
145
146 item = util_hash_table_find_item(ht, key, key_hash);
147 if(item) {
148 /* TODO: key/value destruction? */
149 item->value = value;
150 return;
151 }
152
153 item = malloc(sizeof(struct util_hash_table_item));
154 if(!item)
155 return;
156
157 item->key = key;
158 item->value = value;
159
160 iter = util_hash_insert(ht->head, key_hash, item);
161 if(util_hash_iter_is_null(iter)) {
162 free(item);
163 return;
164 }
165}
166
167drm_private void *util_hash_table_get(struct util_hash_table *ht, void *key)
168{
169 unsigned key_hash;
170 struct util_hash_table_item *item;
171
172 assert(ht);
173 if (!ht)
174 return NULL;
175
176 key_hash = ht->make_hash(key);
177
178 item = util_hash_table_find_item(ht, key, key_hash);
179 if(!item)
180 return NULL;
181
182 return item->value;
183}
184
185drm_private void util_hash_table_remove(struct util_hash_table *ht, void *key)
186{
187 unsigned key_hash;
188 struct util_hash_iter iter;
189 struct util_hash_table_item *item;
190
191 assert(ht);
192 if (!ht)
193 return;
194
195 key_hash = ht->make_hash(key);
196
197 iter = util_hash_table_find_iter(ht, key, key_hash);
198 if(util_hash_iter_is_null(iter))
199 return;
200
201 item = util_hash_table_item(iter);
202 assert(item);
203 free(item);
204
205 util_hash_erase(ht->head, iter);
206}
207
208drm_private void util_hash_table_clear(struct util_hash_table *ht)
209{
210 struct util_hash_iter iter;
211 struct util_hash_table_item *item;
212
213 assert(ht);
214 if (!ht)
215 return;
216
217 iter = util_hash_first_node(ht->head);
218 while (!util_hash_iter_is_null(iter)) {
219 item = (struct util_hash_table_item *)util_hash_take(ht->head, util_hash_iter_key(iter));
220 free(item);
221 iter = util_hash_first_node(ht->head);
222 }
223}
224
225drm_private void util_hash_table_foreach(struct util_hash_table *ht,
226 void (*callback)(void *key, void *value, void *data),
227 void *data)
228{
229 struct util_hash_iter iter;
230 struct util_hash_table_item *item;
231
232 assert(ht);
233 if (!ht)
234 return;
235
236 iter = util_hash_first_node(ht->head);
237 while (!util_hash_iter_is_null(iter)) {
238 item = (struct util_hash_table_item *)util_hash_iter_data(iter);
239 callback(item->key, item->value, data);
240 iter = util_hash_iter_next(iter);
241 }
242}
243
244drm_private void util_hash_table_destroy(struct util_hash_table *ht)
245{
246 struct util_hash_iter iter;
247 struct util_hash_table_item *item;
248
249 assert(ht);
250 if (!ht)
251 return;
252
253 iter = util_hash_first_node(ht->head);
254 while (!util_hash_iter_is_null(iter)) {
255 item = (struct util_hash_table_item *)util_hash_iter_data(iter);
256 free(item);
257 iter = util_hash_iter_next(iter);
258 }
259
260 util_hash_delete(ht->head);
261 free(ht);
262}
diff --git a/amdgpu/util_hash_table.h b/amdgpu/util_hash_table.h
new file mode 100644
index 00000000..e0001289
--- /dev/null
+++ b/amdgpu/util_hash_table.h
@@ -0,0 +1,73 @@
1/**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28/**
29 * General purpose hash table.
30 *
31 * @author José Fonseca <jfonseca@vmware.com>
32 */
33
34#ifndef U_HASH_TABLE_H_
35#define U_HASH_TABLE_H_
36
37#ifdef HAVE_CONFIG_H
38#include "config.h"
39#endif
40
41#include "libdrm_macros.h"
42
43/**
44 * Generic purpose hash table.
45 */
46struct util_hash_table;
47
48/**
49 * Create an hash table.
50 *
51 * @param hash hash function
52 * @param compare should return 0 for two equal keys.
53 */
54drm_private struct util_hash_table *
55util_hash_table_create(unsigned (*hash)(void *key),
56 int (*compare)(void *key1, void *key2));
57
58drm_private void
59util_hash_table_set(struct util_hash_table *ht, void *key, void *value);
60
61drm_private void *util_hash_table_get(struct util_hash_table *ht, void *key);
62
63drm_private void util_hash_table_remove(struct util_hash_table *ht, void *key);
64
65drm_private void util_hash_table_clear(struct util_hash_table *ht);
66
67drm_private void util_hash_table_foreach(struct util_hash_table *ht,
68 void (*callback)(void *key, void *value, void *data),
69 void *data);
70
71drm_private void util_hash_table_destroy(struct util_hash_table *ht);
72
73#endif /* U_HASH_TABLE_H_ */
diff --git a/autogen.sh b/autogen.sh
index 3f190bad..c8960971 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,6 +1,14 @@
1#! /bin/sh 1#! /bin/sh
2 2
3test -n "$srcdir" || srcdir=`dirname "$0"` 3srcdir=`dirname "$0"`
4test -n "$srcdir" || srcdir=. 4test -z "$srcdir" && srcdir=.
5autoreconf --force --install --verbose "$srcdir" 5
6test -n "$NOCONFIGURE" || "$srcdir/configure" --enable-maintainer-mode "$@" 6ORIGDIR=`pwd`
7cd "$srcdir"
8
9autoreconf --force --verbose --install || exit 1
10cd "$ORIGDIR" || exit $?
11
12if test -z "$NOCONFIGURE"; then
13 "$srcdir"/configure "$@"
14fi
diff --git a/configure.ac b/configure.ac
index 0eab4ebd..f729fd87 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
20 20
21AC_PREREQ([2.63]) 21AC_PREREQ([2.63])
22AC_INIT([libdrm], 22AC_INIT([libdrm],
23 [2.4.58], 23 [2.4.66],
24 [https://bugs.freedesktop.org/enter_bug.cgi?product=DRI], 24 [https://bugs.freedesktop.org/enter_bug.cgi?product=DRI],
25 [libdrm]) 25 [libdrm])
26 26
@@ -29,19 +29,32 @@ AC_CONFIG_SRCDIR([Makefile.am])
29AC_CONFIG_MACRO_DIR([m4]) 29AC_CONFIG_MACRO_DIR([m4])
30AC_CONFIG_AUX_DIR([build-aux]) 30AC_CONFIG_AUX_DIR([build-aux])
31 31
32# Require xorg-macros minimum of 1.12 for XORG_WITH_XSLTPROC
33m4_ifndef([XORG_MACROS_VERSION],
34 [m4_fatal([must install xorg-macros 1.12 or later before running autoconf/autogen])])
35XORG_MACROS_VERSION(1.12)
36XORG_WITH_XSLTPROC
37XORG_MANPAGE_SECTIONS
38
32AM_INIT_AUTOMAKE([1.10 foreign dist-bzip2]) 39AM_INIT_AUTOMAKE([1.10 foreign dist-bzip2])
33AM_MAINTAINER_MODE([enable])
34 40
35# Enable quiet compiles on automake 1.11. 41# Enable quiet compiles on automake 1.11.
36m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) 42m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
37 43
38# Check for programs 44# Check for programs
39AC_PROG_CC 45AC_PROG_CC
46AC_PROG_CC_C99
47
48if test "x$ac_cv_prog_cc_c99" = xno; then
49 AC_MSG_ERROR([Building libdrm requires C99 enabled compiler])
50fi
40 51
41AC_USE_SYSTEM_EXTENSIONS 52AC_USE_SYSTEM_EXTENSIONS
42AC_SYS_LARGEFILE 53AC_SYS_LARGEFILE
43AC_FUNC_ALLOCA 54AC_FUNC_ALLOCA
44 55
56AC_CHECK_HEADERS([sys/mkdev.h sys/sysctl.h])
57
45# Initialize libtool 58# Initialize libtool
46LT_PREREQ([2.2]) 59LT_PREREQ([2.2])
47LT_INIT([disable-static]) 60LT_INIT([disable-static])
@@ -60,12 +73,12 @@ AC_ARG_ENABLE([udev],
60 73
61AC_ARG_ENABLE(libkms, 74AC_ARG_ENABLE(libkms,
62 AS_HELP_STRING([--disable-libkms], 75 AS_HELP_STRING([--disable-libkms],
63 [Disable KMS mm abstraction library (default: auto)]), 76 [Disable KMS mm abstraction library (default: auto, enabled on supported platforms)]),
64 [LIBKMS=$enableval], [LIBKMS=auto]) 77 [LIBKMS=$enableval], [LIBKMS=auto])
65 78
66AC_ARG_ENABLE(intel, 79AC_ARG_ENABLE(intel,
67 AS_HELP_STRING([--disable-intel], 80 AS_HELP_STRING([--disable-intel],
68 [Enable support for intel's KMS API (default: auto)]), 81 [Enable support for intel's KMS API (default: auto, enabled on x86)]),
69 [INTEL=$enableval], [INTEL=auto]) 82 [INTEL=$enableval], [INTEL=auto])
70 83
71AC_ARG_ENABLE(radeon, 84AC_ARG_ENABLE(radeon,
@@ -73,6 +86,11 @@ AC_ARG_ENABLE(radeon,
73 [Enable support for radeon's KMS API (default: auto)]), 86 [Enable support for radeon's KMS API (default: auto)]),
74 [RADEON=$enableval], [RADEON=auto]) 87 [RADEON=$enableval], [RADEON=auto])
75 88
89AC_ARG_ENABLE(amdgpu,
90 AS_HELP_STRING([--disable-amdgpu],
91 [Enable support for amdgpu's KMS API (default: auto)]),
92 [AMDGPU=$enableval], [AMDGPU=auto])
93
76AC_ARG_ENABLE(nouveau, 94AC_ARG_ENABLE(nouveau,
77 AS_HELP_STRING([--disable-nouveau], 95 AS_HELP_STRING([--disable-nouveau],
78 [Enable support for nouveau's KMS API (default: auto)]), 96 [Enable support for nouveau's KMS API (default: auto)]),
@@ -95,8 +113,8 @@ AC_ARG_ENABLE(exynos-experimental-api,
95 113
96AC_ARG_ENABLE(freedreno, 114AC_ARG_ENABLE(freedreno,
97 AS_HELP_STRING([--disable-freedreno], 115 AS_HELP_STRING([--disable-freedreno],
98 [Enable support for freedreno's KMS API (default: enabled)]), 116 [Enable support for freedreno's KMS API (default: auto, enabled on arm)]),
99 [FREEDRENO=$enableval], [FREEDRENO=yes]) 117 [FREEDRENO=$enableval], [FREEDRENO=auto])
100 118
101AC_ARG_ENABLE(freedreno-kgsl, 119AC_ARG_ENABLE(freedreno-kgsl,
102 AS_HELP_STRING([--enable-freedreno-kgsl], 120 AS_HELP_STRING([--enable-freedreno-kgsl],
@@ -160,8 +178,8 @@ MAYBE_WARN="-Wall -Wextra \
160-Wpacked -Wswitch-enum -Wmissing-format-attribute \ 178-Wpacked -Wswitch-enum -Wmissing-format-attribute \
161-Wstrict-aliasing=2 -Winit-self \ 179-Wstrict-aliasing=2 -Winit-self \
162-Wdeclaration-after-statement -Wold-style-definition \ 180-Wdeclaration-after-statement -Wold-style-definition \
163-Wno-missing-field-initializers -Wno-unused-parameter \ 181-Wno-unused-parameter \
164-Wno-attributes -Wno-long-long -Winline" 182-Wno-attributes -Wno-long-long -Winline -Wshadow"
165 183
166# invalidate cached value if MAYBE_WARN has changed 184# invalidate cached value if MAYBE_WARN has changed
167if test "x$libdrm_cv_warn_maybe" != "x$MAYBE_WARN"; then 185if test "x$libdrm_cv_warn_maybe" != "x$MAYBE_WARN"; then
@@ -197,8 +215,8 @@ AC_CACHE_CHECK([for native atomic primitives], drm_cv_atomic_primitives, [
197 drm_cv_atomic_primitives="none" 215 drm_cv_atomic_primitives="none"
198 216
199 AC_LINK_IFELSE([AC_LANG_PROGRAM([[ 217 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
200 int atomic_add(int i) { return __sync_fetch_and_add (&i, 1); } 218 int atomic_add(int *i) { return __sync_add_and_fetch (i, 1); }
201 int atomic_cmpxchg(int i, int j, int k) { return __sync_val_compare_and_swap (&i, j, k); } 219 int atomic_cmpxchg(int *i, int j, int k) { return __sync_val_compare_and_swap (i, j, k); }
202 ]],[[]])], [drm_cv_atomic_primitives="Intel"],[]) 220 ]],[[]])], [drm_cv_atomic_primitives="Intel"],[])
203 221
204 if test "x$drm_cv_atomic_primitives" = "xnone"; then 222 if test "x$drm_cv_atomic_primitives" = "xnone"; then
@@ -219,45 +237,62 @@ if test "x$drm_cv_atomic_primitives" = "xlibatomic-ops"; then
219 AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 1, [Enable if you have libatomic-ops-dev installed]) 237 AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 1, [Enable if you have libatomic-ops-dev installed])
220fi 238fi
221 239
222if test "x$INTEL" != "xno" -o "x$RADEON" != "xno" -o "x$NOUVEAU" != "xno"; then 240dnl Print out the approapriate message considering the value set be the
223 if test "x$drm_cv_atomic_primitives" = "xnone"; then 241dnl respective in $1.
224 if test "x$INTEL" != "xauto"; then 242dnl $1 - value to be evaluated. Eg. $INTEL, $NOUVEAU, ...
225 if test "x$INTEL" != "xno"; then 243dnl $2 - libdrm shortname. Eg. intel, freedreno, ...
226 AC_MSG_ERROR([libdrm_intel depends upon atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package, or, failing both of those, disable support for Intel GPUs by passing --disable-intel to ./configure]) 244dnl $3 - GPU name/brand. Eg. Intel, NVIDIA Tegra, ...
227 fi 245dnl $4 - Configure switch. Eg. intel, omap-experimental-api, ...
228 else 246AC_DEFUN([LIBDRM_ATOMICS_NOT_FOUND_MSG], [
229 AC_MSG_WARN([Disabling libdrm_intel. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.]) 247 case "x$1" in
230 INTEL=no 248 xyes) AC_MSG_ERROR([libdrm_$2 depends upon atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package, or, failing both of those, disable support for $3 GPUs by passing --disable-$4 to ./configure]) ;;
231 fi 249 xauto) AC_MSG_WARN([Disabling $2. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.]) ;;
232 if test "x$RADEON" != "xauto"; then 250 *) ;;
233 if test "x$RADEON" != "xno"; then 251 esac
234 AC_MSG_ERROR([libdrm_radeon depends upon atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package, or, failing both of those, disable support for Radeon GPUs by passing --disable-radeon to ./configure]) 252])
235 fi 253
236 else 254if test "x$drm_cv_atomic_primitives" = "xnone"; then
237 AC_MSG_WARN([Disabling libdrm_radeon. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.]) 255 LIBDRM_ATOMICS_NOT_FOUND_MSG($INTEL, intel, Intel, intel)
238 RADEON=no 256 INTEL=no
239 fi 257
240 if test "x$NOUVEAU" != "xauto"; then 258 LIBDRM_ATOMICS_NOT_FOUND_MSG($RADEON, radeon, Radeon, radeon)
241 if test "x$NOUVEAU" != "xno"; then 259 RADEON=no
242 AC_MSG_ERROR([libdrm_nouveau depends upon atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package, or, failing both of those, disable support for NVIDIA GPUs by passing --disable-nouveau to ./configure]) 260
243 fi 261 LIBDRM_ATOMICS_NOT_FOUND_MSG($AMDGPU, amdgpu, AMD, amdgpu)
244 else 262 AMDGPU=no
245 AC_MSG_WARN([Disabling libdrm_nouveau. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.]) 263
246 NOUVEAU=no 264 LIBDRM_ATOMICS_NOT_FOUND_MSG($NOUVEAU, nouveau, NVIDIA, nouveau)
247 fi 265 NOUVEAU=no
248 else 266
249 if test "x$INTEL" != "xno"; then 267 LIBDRM_ATOMICS_NOT_FOUND_MSG($OMAP, omap, OMAP, omap-experimental-api)
250 case $host_cpu in 268 OMAP=no
251 i?86|x86_64) INTEL=yes ;; 269
252 *) INTEL=no ;; 270 LIBDRM_ATOMICS_NOT_FOUND_MSG($FREEDRENO, freedreno, Qualcomm Adreno, freedreno)
253 esac 271 FREEDRENO=no
254 fi 272
255 if test "x$RADEON" != "xno"; then 273 LIBDRM_ATOMICS_NOT_FOUND_MSG($TEGRA, tegra, NVIDIA Tegra, tegra-experimental-api)
256 RADEON=yes 274 TEGRA=no
257 fi 275else
258 if test "x$NOUVEAU" != "xno"; then 276 if test "x$INTEL" = xauto; then
259 NOUVEAU=yes 277 case $host_cpu in
260 fi 278 i?86|x86_64) INTEL=yes ;;
279 *) INTEL=no ;;
280 esac
281 fi
282 if test "x$RADEON" = xauto; then
283 RADEON=yes
284 fi
285 if test "x$AMDGPU" = xauto; then
286 AMDGPU=yes
287 fi
288 if test "x$NOUVEAU" = xauto; then
289 NOUVEAU=yes
290 fi
291 if test "x$FREEDRENO" = xauto; then
292 case $host_cpu in
293 arm*|aarch64) FREEDRENO=yes ;;
294 *) FREEDRENO=no ;;
295 esac
261 fi 296 fi
262fi 297fi
263 298
@@ -314,6 +349,11 @@ if test "x$FREEDRENO" = xyes; then
314 AC_DEFINE(HAVE_FREEDRENO, 1, [Have freedreno support]) 349 AC_DEFINE(HAVE_FREEDRENO, 1, [Have freedreno support])
315fi 350fi
316 351
352if test "x$FREEDRENO_KGSL" = xyes; then
353 if test "x$FREEDRENO" != xyes; then
354 AC_MSG_ERROR([Cannot enable freedreno KGSL interface if freedreno is disabled])
355 fi
356fi
317AM_CONDITIONAL(HAVE_FREEDRENO_KGSL, [test "x$FREEDRENO_KGSL" = xyes]) 357AM_CONDITIONAL(HAVE_FREEDRENO_KGSL, [test "x$FREEDRENO_KGSL" = xyes])
318if test "x$FREEDRENO_KGSL" = xyes; then 358if test "x$FREEDRENO_KGSL" = xyes; then
319 AC_DEFINE(HAVE_FREEDRENO_KGSL, 1, [Have freedreno support for KGSL kernel interface]) 359 AC_DEFINE(HAVE_FREEDRENO_KGSL, 1, [Have freedreno support for KGSL kernel interface])
@@ -324,6 +364,33 @@ if test "x$RADEON" = xyes; then
324 AC_DEFINE(HAVE_RADEON, 1, [Have radeon support]) 364 AC_DEFINE(HAVE_RADEON, 1, [Have radeon support])
325fi 365fi
326 366
367# Detect cunit library
368PKG_CHECK_MODULES([CUNIT], [cunit >= 2.1], [have_cunit=yes], [have_cunit=no])
369# If pkg-config does not find cunit, check it using AC_CHECK_LIB. We
370# do this because Debian (Ubuntu) lacks pkg-config file for cunit.
371# fixed in 2.1-2.dfsg-3: http://anonscm.debian.org/cgit/collab-maint/cunit.git/commit/?h=debian
372if test "x${have_cunit}" = "xno"; then
373 AC_CHECK_LIB([cunit], [CU_initialize_registry], [have_cunit=yes], [have_cunit=no])
374 if test "x${have_cunit}" = "xyes"; then
375 CUNIT_LIBS="-lcunit"
376 CUNIT_CFLAGS=""
377 AC_SUBST([CUNIT_LIBS])
378 AC_SUBST([CUNIT_CFLAGS])
379 fi
380fi
381AM_CONDITIONAL(HAVE_CUNIT, [test "x$have_cunit" != "xno"])
382
383AM_CONDITIONAL(HAVE_AMDGPU, [test "x$AMDGPU" = xyes])
384if test "x$AMDGPU" = xyes; then
385 AC_DEFINE(HAVE_AMDGPU, 1, [Have amdgpu support])
386
387 AC_DEFINE(HAVE_CUNIT, [test "x$have_cunit" != "xno"], [Enable CUNIT Have amdgpu support])
388
389 if test "x$have_cunit" = "xno"; then
390 AC_MSG_WARN([Could not find cunit library. Disabling amdgpu tests])
391 fi
392fi
393
327AM_CONDITIONAL(HAVE_TEGRA, [test "x$TEGRA" = xyes]) 394AM_CONDITIONAL(HAVE_TEGRA, [test "x$TEGRA" = xyes])
328if test "x$TEGRA" = xyes; then 395if test "x$TEGRA" = xyes; then
329 AC_DEFINE(HAVE_TEGRA, 1, [Have Tegra support]) 396 AC_DEFINE(HAVE_TEGRA, 1, [Have Tegra support])
@@ -366,9 +433,8 @@ AM_CONDITIONAL(HAVE_LIBUDEV, [test "x$HAVE_LIBUDEV" = xyes])
366 433
367# xsltproc for docbook manpages 434# xsltproc for docbook manpages
368AC_ARG_ENABLE([manpages], 435AC_ARG_ENABLE([manpages],
369 AS_HELP_STRING([--disable-manpages], [disable manpages @<:@default=enabled@:>@]), 436 AS_HELP_STRING([--enable-manpages], [enable manpages @<:@default=auto@:>@]),
370 [MANS=$enableval], [MANS=auto]) 437 [MANS=$enableval], [MANS=auto])
371AC_PATH_PROG(XSLTPROC, xsltproc)
372AM_CONDITIONAL([BUILD_MANPAGES], [test "x$XSLTPROC" != "x" -a "x$MANS" != "xno"]) 438AM_CONDITIONAL([BUILD_MANPAGES], [test "x$XSLTPROC" != "x" -a "x$MANS" != "xno"])
373 439
374# check for offline man-pages stylesheet 440# check for offline man-pages stylesheet
@@ -385,35 +451,38 @@ else
385fi 451fi
386AM_CONDITIONAL([HAVE_MANPAGES_STYLESHEET], [test "x$HAVE_MANPAGES_STYLESHEET" = "xyes"]) 452AM_CONDITIONAL([HAVE_MANPAGES_STYLESHEET], [test "x$HAVE_MANPAGES_STYLESHEET" = "xyes"])
387 453
454AC_ARG_ENABLE(valgrind,
455 [AS_HELP_STRING([--enable-valgrind],
456 [Build libdrm with valgrind support (default: auto)])],
457 [VALGRIND=$enableval], [VALGRIND=auto])
388PKG_CHECK_MODULES(VALGRIND, [valgrind], [have_valgrind=yes], [have_valgrind=no]) 458PKG_CHECK_MODULES(VALGRIND, [valgrind], [have_valgrind=yes], [have_valgrind=no])
389if test "x$have_valgrind" = "xyes"; then 459AC_MSG_CHECKING([whether to enable Valgrind support])
460if test "x$VALGRIND" = xauto; then
461 VALGRIND="$have_valgrind"
462fi
463
464if test "x$VALGRIND" = "xyes"; then
465 if ! test "x$have_valgrind" = xyes; then
466 AC_MSG_ERROR([Valgrind support required but not present])
467 fi
390 AC_DEFINE([HAVE_VALGRIND], 1, [Use valgrind intrinsics to suppress false warnings]) 468 AC_DEFINE([HAVE_VALGRIND], 1, [Use valgrind intrinsics to suppress false warnings])
391fi 469fi
392 470
471AC_MSG_RESULT([$VALGRIND])
472
393AC_ARG_WITH([kernel-source], 473AC_ARG_WITH([kernel-source],
394 [AS_HELP_STRING([--with-kernel-source], 474 [AS_HELP_STRING([--with-kernel-source],
395 [specify path to linux kernel source])], 475 [specify path to linux kernel source])],
396 [kernel_source="$with_kernel_source"]) 476 [kernel_source="$with_kernel_source"])
397AC_SUBST(kernel_source) 477AC_SUBST(kernel_source)
398 478
399dnl Add flags for gcc and g++ 479AC_MSG_CHECKING([whether $CC supports __attribute__(("hidden"))])
400if test "x$GCC" = xyes; then 480AC_LINK_IFELSE([AC_LANG_PROGRAM([
401 # Enable -fvisibility=hidden if using a gcc that supports it 481 int foo_hidden( void ) __attribute__((visibility("hidden")));
402 save_CFLAGS="$CFLAGS" 482])], HAVE_ATTRIBUTE_VISIBILITY="yes"; AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]));
403 AC_MSG_CHECKING([whether $CC supports -fvisibility=hidden])
404 VISIBILITY_CFLAGS="-fvisibility=hidden"
405 CFLAGS="$CFLAGS $VISIBILITY_CFLAGS"
406 AC_LINK_IFELSE([AC_LANG_PROGRAM()], AC_MSG_RESULT([yes]),
407 [VISIBILITY_CFLAGS=""; AC_MSG_RESULT([no])]);
408
409 # Restore CFLAGS; VISIBILITY_CFLAGS are added to it where needed.
410 CFLAGS=$save_CFLAGS
411
412 if test "x$VISIBILITY_CFLAGS" != x; then
413 AC_DEFINE(HAVE_VISIBILITY, 1, [Compiler has -fvisibility support])
414 fi
415 483
416 AC_SUBST([VISIBILITY_CFLAGS]) 484if test "x$HAVE_ATTRIBUTE_VISIBILITY" = xyes; then
485 AC_DEFINE(HAVE_VISIBILITY, 1, [Compiler supports __attribute__(("hidden"))])
417fi 486fi
418 487
419AC_SUBST(WARN_CFLAGS) 488AC_SUBST(WARN_CFLAGS)
@@ -425,6 +494,8 @@ AC_CONFIG_FILES([
425 intel/libdrm_intel.pc 494 intel/libdrm_intel.pc
426 radeon/Makefile 495 radeon/Makefile
427 radeon/libdrm_radeon.pc 496 radeon/libdrm_radeon.pc
497 amdgpu/Makefile
498 amdgpu/libdrm_amdgpu.pc
428 nouveau/Makefile 499 nouveau/Makefile
429 nouveau/libdrm_nouveau.pc 500 nouveau/libdrm_nouveau.pc
430 omap/Makefile 501 omap/Makefile
@@ -440,13 +511,17 @@ AC_CONFIG_FILES([
440 tests/Makefile 511 tests/Makefile
441 tests/modeprint/Makefile 512 tests/modeprint/Makefile
442 tests/modetest/Makefile 513 tests/modetest/Makefile
514 tests/kms/Makefile
443 tests/kmstest/Makefile 515 tests/kmstest/Makefile
444 tests/proptest/Makefile 516 tests/proptest/Makefile
445 tests/radeon/Makefile 517 tests/radeon/Makefile
518 tests/amdgpu/Makefile
446 tests/vbltest/Makefile 519 tests/vbltest/Makefile
447 tests/exynos/Makefile 520 tests/exynos/Makefile
448 tests/tegra/Makefile 521 tests/tegra/Makefile
522 tests/nouveau/Makefile
449 tests/planetest/Makefile 523 tests/planetest/Makefile
524 tests/util/Makefile
450 man/Makefile 525 man/Makefile
451 libdrm.pc]) 526 libdrm.pc])
452AC_OUTPUT 527AC_OUTPUT
@@ -458,6 +533,7 @@ echo " libkms $LIBKMS"
458echo " Intel API $INTEL" 533echo " Intel API $INTEL"
459echo " vmwgfx API $VMWGFX" 534echo " vmwgfx API $VMWGFX"
460echo " Radeon API $RADEON" 535echo " Radeon API $RADEON"
536echo " AMDGPU API $AMDGPU"
461echo " Nouveau API $NOUVEAU" 537echo " Nouveau API $NOUVEAU"
462echo " OMAP API $OMAP" 538echo " OMAP API $OMAP"
463echo " EXYNOS API $EXYNOS" 539echo " EXYNOS API $EXYNOS"
diff --git a/exynos/Makefile.am b/exynos/Makefile.am
index 06bee007..f99f8981 100644
--- a/exynos/Makefile.am
+++ b/exynos/Makefile.am
@@ -1,8 +1,6 @@
1AM_CFLAGS = \ 1AM_CFLAGS = \
2 $(WARN_CFLAGS) \ 2 $(WARN_CFLAGS) \
3 $(VISIBILITY_CFLAGS) \
4 -I$(top_srcdir) \ 3 -I$(top_srcdir) \
5 -I$(top_srcdir)/exynos \
6 $(PTHREADSTUBS_CFLAGS) \ 4 $(PTHREADSTUBS_CFLAGS) \
7 -I$(top_srcdir)/include/drm 5 -I$(top_srcdir)/include/drm
8 6
@@ -14,14 +12,16 @@ libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
14libdrm_exynos_la_SOURCES = \ 12libdrm_exynos_la_SOURCES = \
15 exynos_drm.c \ 13 exynos_drm.c \
16 exynos_fimg2d.c \ 14 exynos_fimg2d.c \
17 fimg2d.h \
18 fimg2d_reg.h 15 fimg2d_reg.h
19 16
20libdrm_exynoscommonincludedir = ${includedir}/exynos 17libdrm_exynoscommonincludedir = ${includedir}/exynos
21libdrm_exynoscommoninclude_HEADERS = exynos_drm.h 18libdrm_exynoscommoninclude_HEADERS = exynos_drm.h exynos_fimg2d.h
22 19
23libdrm_exynosincludedir = ${includedir}/libdrm 20libdrm_exynosincludedir = ${includedir}/libdrm
24libdrm_exynosinclude_HEADERS = exynos_drmif.h 21libdrm_exynosinclude_HEADERS = exynos_drmif.h
25 22
26pkgconfigdir = @pkgconfigdir@ 23pkgconfigdir = @pkgconfigdir@
27pkgconfig_DATA = libdrm_exynos.pc 24pkgconfig_DATA = libdrm_exynos.pc
25
26TESTS = exynos-symbol-check
27EXTRA_DIST = $(TESTS)
diff --git a/exynos/exynos-symbol-check b/exynos/exynos-symbol-check
new file mode 100755
index 00000000..9692caa6
--- /dev/null
+++ b/exynos/exynos-symbol-check
@@ -0,0 +1,40 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.am/libdrm_exynos*_HEADERS
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_exynos.so} | awk '{print $3}'| while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13exynos_bo_create
14exynos_bo_destroy
15exynos_bo_from_name
16exynos_bo_get_info
17exynos_bo_get_name
18exynos_bo_handle
19exynos_bo_map
20exynos_device_create
21exynos_device_destroy
22exynos_prime_fd_to_handle
23exynos_prime_handle_to_fd
24exynos_vidi_connection
25exynos_handle_event
26g2d_blend
27g2d_copy
28g2d_copy_with_scale
29g2d_exec
30g2d_config_event
31g2d_fini
32g2d_init
33g2d_move
34g2d_scale_and_blend
35g2d_solid_fill
36EOF
37done)
38
39test ! -n "$FUNCS" || echo $FUNCS
40test ! -n "$FUNCS"
diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c
index 4c7dd13e..e689781d 100644
--- a/exynos/exynos_drm.c
+++ b/exynos/exynos_drm.c
@@ -32,16 +32,19 @@
32#include <stdio.h> 32#include <stdio.h>
33#include <string.h> 33#include <string.h>
34#include <errno.h> 34#include <errno.h>
35#include <unistd.h>
35 36
36#include <sys/mman.h> 37#include <sys/mman.h>
37#include <linux/stddef.h> 38#include <linux/stddef.h>
38 39
39#include <xf86drm.h> 40#include <xf86drm.h>
40 41
41#include "libdrm.h" 42#include "libdrm_macros.h"
42#include "exynos_drm.h" 43#include "exynos_drm.h"
43#include "exynos_drmif.h" 44#include "exynos_drmif.h"
44 45
46#define U642VOID(x) ((void *)(unsigned long)(x))
47
45/* 48/*
46 * Create exynos drm device object. 49 * Create exynos drm device object.
47 * 50 *
@@ -49,7 +52,7 @@
49 * 52 *
50 * if true, return the device object else NULL. 53 * if true, return the device object else NULL.
51 */ 54 */
52drm_public struct exynos_device * exynos_device_create(int fd) 55struct exynos_device * exynos_device_create(int fd)
53{ 56{
54 struct exynos_device *dev; 57 struct exynos_device *dev;
55 58
@@ -70,7 +73,7 @@ drm_public struct exynos_device * exynos_device_create(int fd)
70 * 73 *
71 * @dev: exynos drm device object. 74 * @dev: exynos drm device object.
72 */ 75 */
73drm_public void exynos_device_destroy(struct exynos_device *dev) 76void exynos_device_destroy(struct exynos_device *dev)
74{ 77{
75 free(dev); 78 free(dev);
76} 79}
@@ -88,7 +91,7 @@ drm_public void exynos_device_destroy(struct exynos_device *dev)
88 * 91 *
89 * if true, return a exynos buffer object else NULL. 92 * if true, return a exynos buffer object else NULL.
90 */ 93 */
91drm_public struct exynos_bo * exynos_bo_create(struct exynos_device *dev, 94struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
92 size_t size, uint32_t flags) 95 size_t size, uint32_t flags)
93{ 96{
94 struct exynos_bo *bo; 97 struct exynos_bo *bo;
@@ -142,7 +145,7 @@ fail:
142 * 145 *
143 * if true, return 0 else negative. 146 * if true, return 0 else negative.
144 */ 147 */
145drm_public int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle, 148int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
146 size_t *size, uint32_t *flags) 149 size_t *size, uint32_t *flags)
147{ 150{
148 int ret; 151 int ret;
@@ -168,7 +171,7 @@ drm_public int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
168 * 171 *
169 * @bo: a exynos buffer object to be destroyed. 172 * @bo: a exynos buffer object to be destroyed.
170 */ 173 */
171drm_public void exynos_bo_destroy(struct exynos_bo *bo) 174void exynos_bo_destroy(struct exynos_bo *bo)
172{ 175{
173 if (!bo) 176 if (!bo)
174 return; 177 return;
@@ -200,7 +203,7 @@ drm_public void exynos_bo_destroy(struct exynos_bo *bo)
200 * if true, return a exynos buffer object else NULL. 203 * if true, return a exynos buffer object else NULL.
201 * 204 *
202 */ 205 */
203drm_public struct exynos_bo * 206struct exynos_bo *
204exynos_bo_from_name(struct exynos_device *dev, uint32_t name) 207exynos_bo_from_name(struct exynos_device *dev, uint32_t name)
205{ 208{
206 struct exynos_bo *bo; 209 struct exynos_bo *bo;
@@ -243,7 +246,7 @@ err_free_bo:
243 * 246 *
244 * if true, return 0 else negative. 247 * if true, return 0 else negative.
245 */ 248 */
246drm_public int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) 249int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name)
247{ 250{
248 if (!bo->name) { 251 if (!bo->name) {
249 struct drm_gem_flink req = { 252 struct drm_gem_flink req = {
@@ -266,7 +269,7 @@ drm_public int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name)
266 return 0; 269 return 0;
267} 270}
268 271
269drm_public uint32_t exynos_bo_handle(struct exynos_bo *bo) 272uint32_t exynos_bo_handle(struct exynos_bo *bo)
270{ 273{
271 return bo->handle; 274 return bo->handle;
272} 275}
@@ -279,24 +282,29 @@ drm_public uint32_t exynos_bo_handle(struct exynos_bo *bo)
279 * 282 *
280 * if true, user pointer mmaped else NULL. 283 * if true, user pointer mmaped else NULL.
281 */ 284 */
282drm_public void *exynos_bo_map(struct exynos_bo *bo) 285void *exynos_bo_map(struct exynos_bo *bo)
283{ 286{
284 if (!bo->vaddr) { 287 if (!bo->vaddr) {
285 struct exynos_device *dev = bo->dev; 288 struct exynos_device *dev = bo->dev;
286 struct drm_exynos_gem_mmap req = { 289 struct drm_mode_map_dumb arg;
287 .handle = bo->handle, 290 void *map = NULL;
288 .size = bo->size,
289 };
290 int ret; 291 int ret;
291 292
292 ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &req); 293 memset(&arg, 0, sizeof(arg));
294 arg.handle = bo->handle;
295
296 ret = drmIoctl(dev->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
293 if (ret) { 297 if (ret) {
294 fprintf(stderr, "failed to mmap[%s].\n", 298 fprintf(stderr, "failed to map dumb buffer[%s].\n",
295 strerror(errno)); 299 strerror(errno));
296 return NULL; 300 return NULL;
297 } 301 }
298 302
299 bo->vaddr = (void *)(uintptr_t)req.mapped; 303 map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
304 dev->fd, arg.offset);
305
306 if (map != MAP_FAILED)
307 bo->vaddr = map;
300 } 308 }
301 309
302 return bo->vaddr; 310 return bo->vaddr;
@@ -311,7 +319,7 @@ drm_public void *exynos_bo_map(struct exynos_bo *bo)
311 * 319 *
312 * @return: 0 on success, -1 on error, and errno will be set 320 * @return: 0 on success, -1 on error, and errno will be set
313 */ 321 */
314drm_public int 322int
315exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle, int *fd) 323exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle, int *fd)
316{ 324{
317 return drmPrimeHandleToFD(dev->fd, handle, 0, fd); 325 return drmPrimeHandleToFD(dev->fd, handle, 0, fd);
@@ -326,7 +334,7 @@ exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle, int *fd)
326 * 334 *
327 * @return: 0 on success, -1 on error, and errno will be set 335 * @return: 0 on success, -1 on error, and errno will be set
328 */ 336 */
329drm_public int 337int
330exynos_prime_fd_to_handle(struct exynos_device *dev, int fd, uint32_t *handle) 338exynos_prime_fd_to_handle(struct exynos_device *dev, int fd, uint32_t *handle)
331{ 339{
332 return drmPrimeFDToHandle(dev->fd, fd, handle); 340 return drmPrimeFDToHandle(dev->fd, fd, handle);
@@ -349,7 +357,7 @@ exynos_prime_fd_to_handle(struct exynos_device *dev, int fd, uint32_t *handle)
349 * 357 *
350 * if true, return 0 else negative. 358 * if true, return 0 else negative.
351 */ 359 */
352drm_public int 360int
353exynos_vidi_connection(struct exynos_device *dev, uint32_t connect, 361exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
354 uint32_t ext, void *edid) 362 uint32_t ext, void *edid)
355{ 363{
@@ -369,3 +377,76 @@ exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
369 377
370 return 0; 378 return 0;
371} 379}
380
381static void
382exynos_handle_vendor(int fd, struct drm_event *e, void *ctx)
383{
384 struct drm_exynos_g2d_event *g2d;
385 struct exynos_event_context *ectx = ctx;
386
387 switch (e->type) {
388 case DRM_EXYNOS_G2D_EVENT:
389 if (ectx->version < 1 || ectx->g2d_event_handler == NULL)
390 break;
391 g2d = (struct drm_exynos_g2d_event *)e;
392 ectx->g2d_event_handler(fd, g2d->cmdlist_no, g2d->tv_sec,
393 g2d->tv_usec, U642VOID(g2d->user_data));
394 break;
395
396 default:
397 break;
398 }
399}
400
401int
402exynos_handle_event(struct exynos_device *dev, struct exynos_event_context *ctx)
403{
404 char buffer[1024];
405 int len, i;
406 struct drm_event *e;
407 struct drm_event_vblank *vblank;
408 drmEventContextPtr evctx = &ctx->base;
409
410 /* The DRM read semantics guarantees that we always get only
411 * complete events. */
412 len = read(dev->fd, buffer, sizeof buffer);
413 if (len == 0)
414 return 0;
415 if (len < (int)sizeof *e)
416 return -1;
417
418 i = 0;
419 while (i < len) {
420 e = (struct drm_event *) &buffer[i];
421 switch (e->type) {
422 case DRM_EVENT_VBLANK:
423 if (evctx->version < 1 ||
424 evctx->vblank_handler == NULL)
425 break;
426 vblank = (struct drm_event_vblank *) e;
427 evctx->vblank_handler(dev->fd,
428 vblank->sequence,
429 vblank->tv_sec,
430 vblank->tv_usec,
431 U642VOID (vblank->user_data));
432 break;
433 case DRM_EVENT_FLIP_COMPLETE:
434 if (evctx->version < 2 ||
435 evctx->page_flip_handler == NULL)
436 break;
437 vblank = (struct drm_event_vblank *) e;
438 evctx->page_flip_handler(dev->fd,
439 vblank->sequence,
440 vblank->tv_sec,
441 vblank->tv_usec,
442 U642VOID (vblank->user_data));
443 break;
444 default:
445 exynos_handle_vendor(dev->fd, e, evctx);
446 break;
447 }
448 i += e->length;
449 }
450
451 return 0;
452}
diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h
index c3c6579e..c3af0ac5 100644
--- a/exynos/exynos_drm.h
+++ b/exynos/exynos_drm.h
@@ -47,38 +47,6 @@ struct drm_exynos_gem_create {
47}; 47};
48 48
49/** 49/**
50 * A structure for getting buffer offset.
51 *
52 * @handle: a pointer to gem object created.
53 * @pad: just padding to be 64-bit aligned.
54 * @offset: relatived offset value of the memory region allocated.
55 * - this value should be set by user.
56 */
57struct drm_exynos_gem_map_off {
58 unsigned int handle;
59 unsigned int pad;
60 uint64_t offset;
61};
62
63/**
64 * A structure for mapping buffer.
65 *
66 * @handle: a handle to gem object created.
67 * @pad: just padding to be 64-bit aligned.
68 * @size: memory size to be mapped.
69 * @mapped: having user virtual address mmaped.
70 * - this variable would be filled by exynos gem module
71 * of kernel side with user virtual address which is allocated
72 * by do_mmap().
73 */
74struct drm_exynos_gem_mmap {
75 unsigned int handle;
76 unsigned int pad;
77 uint64_t size;
78 uint64_t mapped;
79};
80
81/**
82 * A structure to gem information. 50 * A structure to gem information.
83 * 51 *
84 * @handle: a handle to gem object created. 52 * @handle: a handle to gem object created.
@@ -164,8 +132,6 @@ struct drm_exynos_g2d_exec {
164}; 132};
165 133
166#define DRM_EXYNOS_GEM_CREATE 0x00 134#define DRM_EXYNOS_GEM_CREATE 0x00
167#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01
168#define DRM_EXYNOS_GEM_MMAP 0x02
169/* Reserved 0x04 ~ 0x05 for exynos specific gem ioctl */ 135/* Reserved 0x04 ~ 0x05 for exynos specific gem ioctl */
170#define DRM_EXYNOS_GEM_GET 0x04 136#define DRM_EXYNOS_GEM_GET 0x04
171#define DRM_EXYNOS_VIDI_CONNECTION 0x07 137#define DRM_EXYNOS_VIDI_CONNECTION 0x07
@@ -178,12 +144,6 @@ struct drm_exynos_g2d_exec {
178#define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \ 144#define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
179 DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create) 145 DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
180 146
181#define DRM_IOCTL_EXYNOS_GEM_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
182 DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
183
184#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
185 DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
186
187#define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \ 147#define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \
188 DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info) 148 DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info)
189 149
@@ -197,4 +157,16 @@ struct drm_exynos_g2d_exec {
197#define DRM_IOCTL_EXYNOS_G2D_EXEC DRM_IOWR(DRM_COMMAND_BASE + \ 157#define DRM_IOCTL_EXYNOS_G2D_EXEC DRM_IOWR(DRM_COMMAND_BASE + \
198 DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec) 158 DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec)
199 159
160/* EXYNOS specific events */
161#define DRM_EXYNOS_G2D_EVENT 0x80000000
162
163struct drm_exynos_g2d_event {
164 struct drm_event base;
165 __u64 user_data;
166 __u32 tv_sec;
167 __u32 tv_usec;
168 __u32 cmdlist_no;
169 __u32 reserved;
170};
171
200#endif 172#endif
diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h
index c7c1d442..626e3998 100644
--- a/exynos/exynos_drmif.h
+++ b/exynos/exynos_drmif.h
@@ -54,6 +54,25 @@ struct exynos_bo {
54 uint32_t name; 54 uint32_t name;
55}; 55};
56 56
57#define EXYNOS_EVENT_CONTEXT_VERSION 1
58
59/*
60 * Exynos Event Context structure.
61 *
62 * @base: base context (for core events).
63 * @version: version info similar to the one in 'drmEventContext'.
64 * @g2d_event_handler: handler for G2D events.
65 */
66struct exynos_event_context {
67 drmEventContext base;
68
69 int version;
70
71 void (*g2d_event_handler)(int fd, unsigned int cmdlist_no,
72 unsigned int tv_sec, unsigned int tv_usec,
73 void *user_data);
74};
75
57/* 76/*
58 * device related functions: 77 * device related functions:
59 */ 78 */
@@ -83,4 +102,11 @@ int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
83int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect, 102int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
84 uint32_t ext, void *edid); 103 uint32_t ext, void *edid);
85 104
105/*
106 * event handling related functions:
107 */
108int exynos_handle_event(struct exynos_device *dev,
109 struct exynos_event_context *ctx);
110
111
86#endif /* EXYNOS_DRMIF_H_ */ 112#endif /* EXYNOS_DRMIF_H_ */
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c
index ce1ba1ef..7f1d105a 100644
--- a/exynos/exynos_fimg2d.c
+++ b/exynos/exynos_fimg2d.c
@@ -18,16 +18,17 @@
18#include <stdio.h> 18#include <stdio.h>
19#include <string.h> 19#include <string.h>
20#include <errno.h> 20#include <errno.h>
21#include <assert.h>
21 22
22#include <sys/mman.h> 23#include <sys/mman.h>
23#include <linux/stddef.h> 24#include <linux/stddef.h>
24 25
25#include <xf86drm.h> 26#include <xf86drm.h>
26 27
27#include "libdrm.h" 28#include "libdrm_macros.h"
28#include "exynos_drm.h" 29#include "exynos_drm.h"
29#include "fimg2d_reg.h" 30#include "fimg2d_reg.h"
30#include "fimg2d.h" 31#include "exynos_fimg2d.h"
31 32
32#define SET_BF(val, sc, si, scsa, scda, dc, di, dcsa, dcda) \ 33#define SET_BF(val, sc, si, scsa, scda, dc, di, dcsa, dcda) \
33 val.data.src_coeff = sc; \ 34 val.data.src_coeff = sc; \
@@ -41,12 +42,90 @@
41 42
42#define MIN(a, b) ((a) < (b) ? (a) : (b)) 43#define MIN(a, b) ((a) < (b) ? (a) : (b))
43 44
45#define MSG_PREFIX "exynos/fimg2d: "
46
47#define G2D_MAX_CMD_NR 64
48#define G2D_MAX_GEM_CMD_NR 64
49#define G2D_MAX_CMD_LIST_NR 64
50
51struct g2d_context {
52 int fd;
53 unsigned int major;
54 unsigned int minor;
55 struct drm_exynos_g2d_cmd cmd[G2D_MAX_CMD_NR];
56 struct drm_exynos_g2d_cmd cmd_buf[G2D_MAX_GEM_CMD_NR];
57 unsigned int cmd_nr;
58 unsigned int cmd_buf_nr;
59 unsigned int cmdlist_nr;
60 void *event_userdata;
61};
62
63enum g2d_base_addr_reg {
64 g2d_dst = 0,
65 g2d_src
66};
67
68enum e_g2d_dir_mode {
69 G2D_DIR_MODE_POSITIVE = 0,
70 G2D_DIR_MODE_NEGATIVE = 1
71};
72
73union g2d_direction_val {
74 unsigned int val[2];
75 struct {
76 /* SRC_MSK_DIRECT_REG [0:1] (source) */
77 enum e_g2d_dir_mode src_x_direction:1;
78 enum e_g2d_dir_mode src_y_direction:1;
79
80 /* SRC_MSK_DIRECT_REG [2:3] */
81 unsigned int reversed1:2;
82
83 /* SRC_MSK_DIRECT_REG [4:5] (mask) */
84 enum e_g2d_dir_mode mask_x_direction:1;
85 enum e_g2d_dir_mode mask_y_direction:1;
86
87 /* SRC_MSK_DIRECT_REG [6:31] */
88 unsigned int padding1:26;
89
90 /* DST_PAT_DIRECT_REG [0:1] (destination) */
91 enum e_g2d_dir_mode dst_x_direction:1;
92 enum e_g2d_dir_mode dst_y_direction:1;
93
94 /* DST_PAT_DIRECT_REG [2:3] */
95 unsigned int reversed2:2;
96
97 /* DST_PAT_DIRECT_REG [4:5] (pattern) */
98 enum e_g2d_dir_mode pat_x_direction:1;
99 enum e_g2d_dir_mode pat_y_direction:1;
100
101 /* DST_PAT_DIRECT_REG [6:31] */
102 unsigned int padding2:26;
103 } data;
104};
105
106static unsigned int g2d_get_scaling(unsigned int src, unsigned int dst)
107{
108 /*
109 * The G2D hw scaling factor is a normalized inverse of the scaling factor.
110 * For example: When source width is 100 and destination width is 200
111 * (scaling of 2x), then the hw factor is NC * 100 / 200.
112 * The normalization factor (NC) is 2^16 = 0x10000.
113 */
114
115 return ((src << 16) / dst);
116}
117
44static unsigned int g2d_get_blend_op(enum e_g2d_op op) 118static unsigned int g2d_get_blend_op(enum e_g2d_op op)
45{ 119{
46 union g2d_blend_func_val val; 120 union g2d_blend_func_val val;
47 121
48 val.val = 0; 122 val.val = 0;
49 123
124 /*
125 * The switch statement is missing the default branch since
126 * we assume that the caller checks the blending operation
127 * via g2d_validate_blending_op() first.
128 */
50 switch (op) { 129 switch (op) {
51 case G2D_OP_CLEAR: 130 case G2D_OP_CLEAR:
52 case G2D_OP_DISJOINT_CLEAR: 131 case G2D_OP_DISJOINT_CLEAR:
@@ -70,10 +149,9 @@ static unsigned int g2d_get_blend_op(enum e_g2d_op op)
70 SET_BF(val, G2D_COEFF_MODE_ONE, 0, 0, 0, 149 SET_BF(val, G2D_COEFF_MODE_ONE, 0, 0, 0,
71 G2D_COEFF_MODE_SRC_ALPHA, 1, 0, 0); 150 G2D_COEFF_MODE_SRC_ALPHA, 1, 0, 0);
72 break; 151 break;
73 default: 152 case G2D_OP_INTERPOLATE:
74 fprintf(stderr, "Not support operation(%d).\n", op); 153 SET_BF(val, G2D_COEFF_MODE_SRC_ALPHA, 0, 0, 0,
75 SET_BF(val, G2D_COEFF_MODE_ONE, 0, 0, 0, G2D_COEFF_MODE_ZERO, 154 G2D_COEFF_MODE_SRC_ALPHA, 1, 0, 0);
76 0, 0, 0);
77 break; 155 break;
78 } 156 }
79 157
@@ -81,13 +159,81 @@ static unsigned int g2d_get_blend_op(enum e_g2d_op op)
81} 159}
82 160
83/* 161/*
162 * g2d_check_space - check if command buffers have enough space left.
163 *
164 * @ctx: a pointer to g2d_context structure.
165 * @num_cmds: number of (regular) commands.
166 * @num_gem_cmds: number of GEM commands.
167 */
168static unsigned int g2d_check_space(const struct g2d_context *ctx,
169 unsigned int num_cmds, unsigned int num_gem_cmds)
170{
171 if (ctx->cmd_nr + num_cmds >= G2D_MAX_CMD_NR ||
172 ctx->cmd_buf_nr + num_gem_cmds >= G2D_MAX_GEM_CMD_NR)
173 return 1;
174 else
175 return 0;
176}
177
178/*
179 * g2d_validate_select_mode - validate select mode.
180 *
181 * @mode: the mode to validate
182 *
183 * Returns zero for an invalid mode and one otherwise.
184 */
185static int g2d_validate_select_mode(
186 enum e_g2d_select_mode mode)
187{
188 switch (mode) {
189 case G2D_SELECT_MODE_NORMAL:
190 case G2D_SELECT_MODE_FGCOLOR:
191 case G2D_SELECT_MODE_BGCOLOR:
192 return 1;
193 }
194
195 return 0;
196}
197
198/*
199 * g2d_validate_blending_op - validate blending operation.
200 *
201 * @operation: the operation to validate
202 *
203 * Returns zero for an invalid mode and one otherwise.
204 */
205static int g2d_validate_blending_op(
206 enum e_g2d_op operation)
207{
208 switch (operation) {
209 case G2D_OP_CLEAR:
210 case G2D_OP_SRC:
211 case G2D_OP_DST:
212 case G2D_OP_OVER:
213 case G2D_OP_INTERPOLATE:
214 case G2D_OP_DISJOINT_CLEAR:
215 case G2D_OP_DISJOINT_SRC:
216 case G2D_OP_DISJOINT_DST:
217 case G2D_OP_CONJOINT_CLEAR:
218 case G2D_OP_CONJOINT_SRC:
219 case G2D_OP_CONJOINT_DST:
220 return 1;
221 }
222
223 return 0;
224}
225
226/*
84 * g2d_add_cmd - set given command and value to user side command buffer. 227 * g2d_add_cmd - set given command and value to user side command buffer.
85 * 228 *
86 * @ctx: a pointer to g2d_context structure. 229 * @ctx: a pointer to g2d_context structure.
87 * @cmd: command data. 230 * @cmd: command data.
88 * @value: value data. 231 * @value: value data.
232 *
233 * The caller has to make sure that the commands buffers have enough space
234 * left to hold the command. Use g2d_check_space() to ensure this.
89 */ 235 */
90static int g2d_add_cmd(struct g2d_context *ctx, unsigned long cmd, 236static void g2d_add_cmd(struct g2d_context *ctx, unsigned long cmd,
91 unsigned long value) 237 unsigned long value)
92{ 238{
93 switch (cmd & ~(G2D_BUF_USERPTR)) { 239 switch (cmd & ~(G2D_BUF_USERPTR)) {
@@ -97,28 +243,53 @@ static int g2d_add_cmd(struct g2d_context *ctx, unsigned long cmd,
97 case DST_PLANE2_BASE_ADDR_REG: 243 case DST_PLANE2_BASE_ADDR_REG:
98 case PAT_BASE_ADDR_REG: 244 case PAT_BASE_ADDR_REG:
99 case MASK_BASE_ADDR_REG: 245 case MASK_BASE_ADDR_REG:
100 if (ctx->cmd_buf_nr >= G2D_MAX_GEM_CMD_NR) { 246 assert(ctx->cmd_buf_nr < G2D_MAX_GEM_CMD_NR);
101 fprintf(stderr, "Overflow cmd_gem size.\n");
102 return -EINVAL;
103 }
104 247
105 ctx->cmd_buf[ctx->cmd_buf_nr].offset = cmd; 248 ctx->cmd_buf[ctx->cmd_buf_nr].offset = cmd;
106 ctx->cmd_buf[ctx->cmd_buf_nr].data = value; 249 ctx->cmd_buf[ctx->cmd_buf_nr].data = value;
107 ctx->cmd_buf_nr++; 250 ctx->cmd_buf_nr++;
108 break; 251 break;
109 default: 252 default:
110 if (ctx->cmd_nr >= G2D_MAX_CMD_NR) { 253 assert(ctx->cmd_nr < G2D_MAX_CMD_NR);
111 fprintf(stderr, "Overflow cmd size.\n");
112 return -EINVAL;
113 }
114 254
115 ctx->cmd[ctx->cmd_nr].offset = cmd; 255 ctx->cmd[ctx->cmd_nr].offset = cmd;
116 ctx->cmd[ctx->cmd_nr].data = value; 256 ctx->cmd[ctx->cmd_nr].data = value;
117 ctx->cmd_nr++; 257 ctx->cmd_nr++;
118 break; 258 break;
119 } 259 }
260}
261
262/*
263 * g2d_add_base_addr - helper function to set dst/src base address register.
264 *
265 * @ctx: a pointer to g2d_context structure.
266 * @img: a pointer to the dst/src g2d_image structure.
267 * @reg: the register that should be set.
268 */
269static void g2d_add_base_addr(struct g2d_context *ctx, struct g2d_image *img,
270 enum g2d_base_addr_reg reg)
271{
272 const unsigned long cmd = (reg == g2d_dst) ?
273 DST_BASE_ADDR_REG : SRC_BASE_ADDR_REG;
120 274
121 return TRUE; 275 if (img->buf_type == G2D_IMGBUF_USERPTR)
276 g2d_add_cmd(ctx, cmd | G2D_BUF_USERPTR,
277 (unsigned long)&img->user_ptr[0]);
278 else
279 g2d_add_cmd(ctx, cmd, img->bo[0]);
280}
281
282/*
283 * g2d_set_direction - setup direction register (useful for overlapping blits).
284 *
285 * @ctx: a pointer to g2d_context structure.
286 * @dir: a pointer to the g2d_direction_val structure.
287 */
288static void g2d_set_direction(struct g2d_context *ctx,
289 const union g2d_direction_val *dir)
290{
291 g2d_add_cmd(ctx, SRC_MASK_DIRECT_REG, dir->val[0]);
292 g2d_add_cmd(ctx, DST_PAT_DIRECT_REG, dir->val[1]);
122} 293}
123 294
124/* 295/*
@@ -136,42 +307,47 @@ static void g2d_reset(struct g2d_context *ctx)
136} 307}
137 308
138/* 309/*
139 * g2d_flush - summit all commands and values in user side command buffer 310 * g2d_flush - submit all commands and values in user side command buffer
140 * to command queue aware of fimg2d dma. 311 * to command queue aware of fimg2d dma.
141 * 312 *
142 * @ctx: a pointer to g2d_context structure. 313 * @ctx: a pointer to g2d_context structure.
143 * 314 *
144 * This function should be called after all commands and values to user 315 * This function should be called after all commands and values to user
145 * side command buffer is set to summit that buffer to kernel side driver. 316 * side command buffer are set. It submits that buffer to the kernel side driver.
146 */ 317 */
147static int g2d_flush(struct g2d_context *ctx) 318static int g2d_flush(struct g2d_context *ctx)
148{ 319{
149 int ret; 320 int ret;
150 struct drm_exynos_g2d_set_cmdlist cmdlist; 321 struct drm_exynos_g2d_set_cmdlist cmdlist = {0};
151 322
152 if (ctx->cmd_nr == 0 && ctx->cmd_buf_nr == 0) 323 if (ctx->cmd_nr == 0 && ctx->cmd_buf_nr == 0)
153 return FALSE; 324 return 0;
154 325
155 if (ctx->cmdlist_nr >= G2D_MAX_CMD_LIST_NR) { 326 if (ctx->cmdlist_nr >= G2D_MAX_CMD_LIST_NR) {
156 fprintf(stderr, "Overflow cmdlist.\n"); 327 fprintf(stderr, MSG_PREFIX "command list overflow.\n");
157 return -EINVAL; 328 return -EINVAL;
158 } 329 }
159 330
160 memset(&cmdlist, 0, sizeof(struct drm_exynos_g2d_set_cmdlist));
161
162 cmdlist.cmd = (uint64_t)(uintptr_t)&ctx->cmd[0]; 331 cmdlist.cmd = (uint64_t)(uintptr_t)&ctx->cmd[0];
163 cmdlist.cmd_buf = (uint64_t)(uintptr_t)&ctx->cmd_buf[0]; 332 cmdlist.cmd_buf = (uint64_t)(uintptr_t)&ctx->cmd_buf[0];
164 cmdlist.cmd_nr = ctx->cmd_nr; 333 cmdlist.cmd_nr = ctx->cmd_nr;
165 cmdlist.cmd_buf_nr = ctx->cmd_buf_nr; 334 cmdlist.cmd_buf_nr = ctx->cmd_buf_nr;
166 cmdlist.event_type = G2D_EVENT_NOT; 335
167 cmdlist.user_data = 0; 336 if (ctx->event_userdata) {
337 cmdlist.event_type = G2D_EVENT_NONSTOP;
338 cmdlist.user_data = (uint64_t)(uintptr_t)(ctx->event_userdata);
339 ctx->event_userdata = NULL;
340 } else {
341 cmdlist.event_type = G2D_EVENT_NOT;
342 cmdlist.user_data = 0;
343 }
168 344
169 ctx->cmd_nr = 0; 345 ctx->cmd_nr = 0;
170 ctx->cmd_buf_nr = 0; 346 ctx->cmd_buf_nr = 0;
171 347
172 ret = drmIoctl(ctx->fd, DRM_IOCTL_EXYNOS_G2D_SET_CMDLIST, &cmdlist); 348 ret = drmIoctl(ctx->fd, DRM_IOCTL_EXYNOS_G2D_SET_CMDLIST, &cmdlist);
173 if (ret < 0) { 349 if (ret < 0) {
174 fprintf(stderr, "failed to set cmdlist.\n"); 350 fprintf(stderr, MSG_PREFIX "failed to set cmdlist.\n");
175 return ret; 351 return ret;
176 } 352 }
177 353
@@ -183,9 +359,9 @@ static int g2d_flush(struct g2d_context *ctx)
183/** 359/**
184 * g2d_init - create a new g2d context and get hardware version. 360 * g2d_init - create a new g2d context and get hardware version.
185 * 361 *
186 * fd: a file descriptor to drm device driver opened. 362 * fd: a file descriptor to an opened drm device.
187 */ 363 */
188drm_public struct g2d_context *g2d_init(int fd) 364struct g2d_context *g2d_init(int fd)
189{ 365{
190 struct drm_exynos_g2d_get_ver ver; 366 struct drm_exynos_g2d_get_ver ver;
191 struct g2d_context *ctx; 367 struct g2d_context *ctx;
@@ -193,7 +369,7 @@ drm_public struct g2d_context *g2d_init(int fd)
193 369
194 ctx = calloc(1, sizeof(*ctx)); 370 ctx = calloc(1, sizeof(*ctx));
195 if (!ctx) { 371 if (!ctx) {
196 fprintf(stderr, "failed to allocate context.\n"); 372 fprintf(stderr, MSG_PREFIX "failed to allocate context.\n");
197 return NULL; 373 return NULL;
198 } 374 }
199 375
@@ -201,7 +377,7 @@ drm_public struct g2d_context *g2d_init(int fd)
201 377
202 ret = drmIoctl(fd, DRM_IOCTL_EXYNOS_G2D_GET_VER, &ver); 378 ret = drmIoctl(fd, DRM_IOCTL_EXYNOS_G2D_GET_VER, &ver);
203 if (ret < 0) { 379 if (ret < 0) {
204 fprintf(stderr, "failed to get version.\n"); 380 fprintf(stderr, MSG_PREFIX "failed to get version.\n");
205 free(ctx); 381 free(ctx);
206 return NULL; 382 return NULL;
207 } 383 }
@@ -209,14 +385,29 @@ drm_public struct g2d_context *g2d_init(int fd)
209 ctx->major = ver.major; 385 ctx->major = ver.major;
210 ctx->minor = ver.minor; 386 ctx->minor = ver.minor;
211 387
212 printf("g2d version(%d.%d).\n", ctx->major, ctx->minor); 388 printf(MSG_PREFIX "G2D version (%d.%d).\n", ctx->major, ctx->minor);
213 return ctx; 389 return ctx;
214} 390}
215 391
216drm_public void g2d_fini(struct g2d_context *ctx) 392void g2d_fini(struct g2d_context *ctx)
217{ 393{
218 if (ctx) 394 free(ctx);
219 free(ctx); 395}
396
397/**
398 * g2d_config_event - setup userdata configuration for a g2d event.
399 * The next invocation of a g2d call (e.g. g2d_solid_fill) is
400 * then going to flag the command buffer as 'nonstop'.
401 * Completion of the command buffer execution can then be
402 * determined by using drmHandleEvent on the DRM fd.
403 * The userdata is 'consumed' in the process.
404 *
405 * @ctx: a pointer to g2d_context structure.
406 * @userdata: a pointer to the user data
407 */
408void g2d_config_event(struct g2d_context *ctx, void *userdata)
409{
410 ctx->event_userdata = userdata;
220} 411}
221 412
222/** 413/**
@@ -224,7 +415,7 @@ drm_public void g2d_fini(struct g2d_context *ctx)
224 * 415 *
225 * @ctx: a pointer to g2d_context structure. 416 * @ctx: a pointer to g2d_context structure.
226 */ 417 */
227drm_public int g2d_exec(struct g2d_context *ctx) 418int g2d_exec(struct g2d_context *ctx)
228{ 419{
229 struct drm_exynos_g2d_exec exec; 420 struct drm_exynos_g2d_exec exec;
230 int ret; 421 int ret;
@@ -236,7 +427,7 @@ drm_public int g2d_exec(struct g2d_context *ctx)
236 427
237 ret = drmIoctl(ctx->fd, DRM_IOCTL_EXYNOS_G2D_EXEC, &exec); 428 ret = drmIoctl(ctx->fd, DRM_IOCTL_EXYNOS_G2D_EXEC, &exec);
238 if (ret < 0) { 429 if (ret < 0) {
239 fprintf(stderr, "failed to execute.\n"); 430 fprintf(stderr, MSG_PREFIX "failed to execute.\n");
240 return ret; 431 return ret;
241 } 432 }
242 433
@@ -256,7 +447,7 @@ drm_public int g2d_exec(struct g2d_context *ctx)
256 * @w: width value to buffer filled with given color data. 447 * @w: width value to buffer filled with given color data.
257 * @h: height value to buffer filled with given color data. 448 * @h: height value to buffer filled with given color data.
258 */ 449 */
259drm_public int 450int
260g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img, 451g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
261 unsigned int x, unsigned int y, unsigned int w, 452 unsigned int x, unsigned int y, unsigned int w,
262 unsigned int h) 453 unsigned int h)
@@ -264,15 +455,12 @@ g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
264 union g2d_bitblt_cmd_val bitblt; 455 union g2d_bitblt_cmd_val bitblt;
265 union g2d_point_val pt; 456 union g2d_point_val pt;
266 457
458 if (g2d_check_space(ctx, 7, 1))
459 return -ENOSPC;
460
267 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_NORMAL); 461 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_NORMAL);
268 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, img->color_mode); 462 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, img->color_mode);
269 463 g2d_add_base_addr(ctx, img, g2d_dst);
270 if (img->buf_type == G2D_IMGBUF_USERPTR)
271 g2d_add_cmd(ctx, DST_BASE_ADDR_REG | G2D_BUF_USERPTR,
272 (unsigned long)&img->user_ptr[0]);
273 else
274 g2d_add_cmd(ctx, DST_BASE_ADDR_REG, img->bo[0]);
275
276 g2d_add_cmd(ctx, DST_STRIDE_REG, img->stride); 464 g2d_add_cmd(ctx, DST_STRIDE_REG, img->stride);
277 465
278 if (x + w > img->width) 466 if (x + w > img->width)
@@ -280,15 +468,12 @@ g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
280 if (y + h > img->height) 468 if (y + h > img->height)
281 h = img->height - y; 469 h = img->height - y;
282 470
283 pt.val = 0;
284 pt.data.x = x; 471 pt.data.x = x;
285 pt.data.y = y; 472 pt.data.y = y;
286 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val); 473 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val);
287 474
288 pt.val = 0;
289 pt.data.x = x + w; 475 pt.data.x = x + w;
290 pt.data.y = y + h; 476 pt.data.y = y + h;
291
292 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val); 477 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val);
293 478
294 g2d_add_cmd(ctx, SF_COLOR_REG, img->color); 479 g2d_add_cmd(ctx, SF_COLOR_REG, img->color);
@@ -297,9 +482,7 @@ g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
297 bitblt.data.fast_solid_color_fill_en = 1; 482 bitblt.data.fast_solid_color_fill_en = 1;
298 g2d_add_cmd(ctx, BITBLT_COMMAND_REG, bitblt.val); 483 g2d_add_cmd(ctx, BITBLT_COMMAND_REG, bitblt.val);
299 484
300 g2d_flush(ctx); 485 return g2d_flush(ctx);
301
302 return 0;
303} 486}
304 487
305/** 488/**
@@ -317,7 +500,7 @@ g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
317 * @w: width value to source and destination buffers. 500 * @w: width value to source and destination buffers.
318 * @h: height value to source and destination buffers. 501 * @h: height value to source and destination buffers.
319 */ 502 */
320drm_public int 503int
321g2d_copy(struct g2d_context *ctx, struct g2d_image *src, 504g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
322 struct g2d_image *dst, unsigned int src_x, unsigned int src_y, 505 struct g2d_image *dst, unsigned int src_x, unsigned int src_y,
323 unsigned int dst_x, unsigned dst_y, unsigned int w, 506 unsigned int dst_x, unsigned dst_y, unsigned int w,
@@ -325,27 +508,7 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
325{ 508{
326 union g2d_rop4_val rop4; 509 union g2d_rop4_val rop4;
327 union g2d_point_val pt; 510 union g2d_point_val pt;
328 unsigned int src_w = 0, src_h = 0, dst_w = 0, dst_h = 0; 511 unsigned int src_w, src_h, dst_w, dst_h;
329
330 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
331 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
332 if (dst->buf_type == G2D_IMGBUF_USERPTR)
333 g2d_add_cmd(ctx, DST_BASE_ADDR_REG | G2D_BUF_USERPTR,
334 (unsigned long)&dst->user_ptr[0]);
335 else
336 g2d_add_cmd(ctx, DST_BASE_ADDR_REG, dst->bo[0]);
337
338 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
339
340 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
341 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
342 if (src->buf_type == G2D_IMGBUF_USERPTR)
343 g2d_add_cmd(ctx, SRC_BASE_ADDR_REG | G2D_BUF_USERPTR,
344 (unsigned long)&src->user_ptr[0]);
345 else
346 g2d_add_cmd(ctx, SRC_BASE_ADDR_REG, src->bo[0]);
347
348 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
349 512
350 src_w = w; 513 src_w = w;
351 src_h = h; 514 src_h = h;
@@ -365,25 +528,33 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
365 h = MIN(src_h, dst_h); 528 h = MIN(src_h, dst_h);
366 529
367 if (w <= 0 || h <= 0) { 530 if (w <= 0 || h <= 0) {
368 fprintf(stderr, "invalid width or height.\n"); 531 fprintf(stderr, MSG_PREFIX "invalid width or height.\n");
369 g2d_reset(ctx);
370 return -EINVAL; 532 return -EINVAL;
371 } 533 }
372 534
373 pt.val = 0; 535 if (g2d_check_space(ctx, 11, 2))
536 return -ENOSPC;
537
538 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
539 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
540 g2d_add_base_addr(ctx, dst, g2d_dst);
541 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
542
543 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
544 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
545 g2d_add_base_addr(ctx, src, g2d_src);
546 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
547
374 pt.data.x = src_x; 548 pt.data.x = src_x;
375 pt.data.y = src_y; 549 pt.data.y = src_y;
376 g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val); 550 g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val);
377 pt.val = 0;
378 pt.data.x = src_x + w; 551 pt.data.x = src_x + w;
379 pt.data.y = src_y + h; 552 pt.data.y = src_y + h;
380 g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val); 553 g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val);
381 554
382 pt.val = 0;
383 pt.data.x = dst_x; 555 pt.data.x = dst_x;
384 pt.data.y = dst_y; 556 pt.data.y = dst_y;
385 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val); 557 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val);
386 pt.val = 0;
387 pt.data.x = dst_x + w; 558 pt.data.x = dst_x + w;
388 pt.data.y = dst_y + h; 559 pt.data.y = dst_y + h;
389 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val); 560 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val);
@@ -392,9 +563,102 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
392 rop4.data.unmasked_rop3 = G2D_ROP3_SRC; 563 rop4.data.unmasked_rop3 = G2D_ROP3_SRC;
393 g2d_add_cmd(ctx, ROP4_REG, rop4.val); 564 g2d_add_cmd(ctx, ROP4_REG, rop4.val);
394 565
395 g2d_flush(ctx); 566 return g2d_flush(ctx);
567}
396 568
397 return 0; 569/**
570 * g2d_move - copy content inside single buffer.
571 * Similar to libc's memmove() this copies a rectangular
572 * region of the provided buffer to another location, while
573 * properly handling the situation where source and
574 * destination rectangle overlap.
575 *
576 * @ctx: a pointer to g2d_context structure.
577 * @img: a pointer to g2d_image structure providing
578 * buffer information.
579 * @src_x: x position of source rectangle.
580 * @src_y: y position of source rectangle.
581 * @dst_x: x position of destination rectangle.
582 * @dst_y: y position of destination rectangle.
583 * @w: width of rectangle to move.
584 * @h: height of rectangle to move.
585 */
586int
587g2d_move(struct g2d_context *ctx, struct g2d_image *img,
588 unsigned int src_x, unsigned int src_y,
589 unsigned int dst_x, unsigned dst_y, unsigned int w,
590 unsigned int h)
591{
592 union g2d_rop4_val rop4;
593 union g2d_point_val pt;
594 union g2d_direction_val dir;
595 unsigned int src_w, src_h, dst_w, dst_h;
596
597 src_w = w;
598 src_h = h;
599 if (src_x + img->width > w)
600 src_w = img->width - src_x;
601 if (src_y + img->height > h)
602 src_h = img->height - src_y;
603
604 dst_w = w;
605 dst_h = w;
606 if (dst_x + img->width > w)
607 dst_w = img->width - dst_x;
608 if (dst_y + img->height > h)
609 dst_h = img->height - dst_y;
610
611 w = MIN(src_w, dst_w);
612 h = MIN(src_h, dst_h);
613
614 if (w == 0 || h == 0) {
615 fprintf(stderr, MSG_PREFIX "invalid width or height.\n");
616 return -EINVAL;
617 }
618
619 if (g2d_check_space(ctx, 13, 2))
620 return -ENOSPC;
621
622 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
623 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
624
625 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, img->color_mode);
626 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, img->color_mode);
627
628 g2d_add_base_addr(ctx, img, g2d_dst);
629 g2d_add_base_addr(ctx, img, g2d_src);
630
631 g2d_add_cmd(ctx, DST_STRIDE_REG, img->stride);
632 g2d_add_cmd(ctx, SRC_STRIDE_REG, img->stride);
633
634 dir.val[0] = dir.val[1] = 0;
635
636 if (dst_x >= src_x)
637 dir.data.src_x_direction = dir.data.dst_x_direction = 1;
638 if (dst_y >= src_y)
639 dir.data.src_y_direction = dir.data.dst_y_direction = 1;
640
641 g2d_set_direction(ctx, &dir);
642
643 pt.data.x = src_x;
644 pt.data.y = src_y;
645 g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val);
646 pt.data.x = src_x + w;
647 pt.data.y = src_y + h;
648 g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val);
649
650 pt.data.x = dst_x;
651 pt.data.y = dst_y;
652 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val);
653 pt.data.x = dst_x + w;
654 pt.data.y = dst_y + h;
655 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val);
656
657 rop4.val = 0;
658 rop4.data.unmasked_rop3 = G2D_ROP3_SRC;
659 g2d_add_cmd(ctx, ROP4_REG, rop4.val);
660
661 return g2d_flush(ctx);
398} 662}
399 663
400/** 664/**
@@ -417,7 +681,7 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
417 * @negative: indicate that it uses color negative to source and 681 * @negative: indicate that it uses color negative to source and
418 * destination buffers. 682 * destination buffers.
419 */ 683 */
420drm_public int 684int
421g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src, 685g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
422 struct g2d_image *dst, unsigned int src_x, 686 struct g2d_image *dst, unsigned int src_x,
423 unsigned int src_y, unsigned int src_w, 687 unsigned int src_y, unsigned int src_w,
@@ -427,37 +691,23 @@ g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
427{ 691{
428 union g2d_rop4_val rop4; 692 union g2d_rop4_val rop4;
429 union g2d_point_val pt; 693 union g2d_point_val pt;
430 unsigned int scale; 694 unsigned int scale, repeat_pad;
431 double scale_x = 0.0f, scale_y = 0.0f; 695 unsigned int scale_x, scale_y;
432
433 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
434 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
435 if (dst->buf_type == G2D_IMGBUF_USERPTR)
436 g2d_add_cmd(ctx, DST_BASE_ADDR_REG | G2D_BUF_USERPTR,
437 (unsigned long)&dst->user_ptr[0]);
438 else
439 g2d_add_cmd(ctx, DST_BASE_ADDR_REG, dst->bo[0]);
440 696
441 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride); 697 /* Sanitize this parameter to facilitate space computation below. */
442 698 if (negative)
443 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL); 699 negative = 1;
444 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
445 if (src->buf_type == G2D_IMGBUF_USERPTR)
446 g2d_add_cmd(ctx, SRC_BASE_ADDR_REG | G2D_BUF_USERPTR,
447 (unsigned long)&src->user_ptr[0]);
448 else
449 g2d_add_cmd(ctx, SRC_BASE_ADDR_REG, src->bo[0]);
450
451 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
452 700
453 if (src_w == dst_w && src_h == dst_h) 701 if (src_w == dst_w && src_h == dst_h)
454 scale = 0; 702 scale = 0;
455 else { 703 else {
456 scale = 1; 704 scale = 1;
457 scale_x = (double)src_w / (double)dst_w; 705 scale_x = g2d_get_scaling(src_w, dst_w);
458 scale_y = (double)src_h / (double)dst_h; 706 scale_y = g2d_get_scaling(src_h, dst_h);
459 } 707 }
460 708
709 repeat_pad = src->repeat_mode == G2D_REPEAT_MODE_PAD ? 1 : 0;
710
461 if (src_x + src_w > src->width) 711 if (src_x + src_w > src->width)
462 src_w = src->width - src_x; 712 src_w = src->width - src_x;
463 if (src_y + src_h > src->height) 713 if (src_y + src_h > src->height)
@@ -469,53 +719,63 @@ g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
469 dst_h = dst->height - dst_y; 719 dst_h = dst->height - dst_y;
470 720
471 if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) { 721 if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) {
472 fprintf(stderr, "invalid width or height.\n"); 722 fprintf(stderr, MSG_PREFIX "invalid width or height.\n");
473 g2d_reset(ctx);
474 return -EINVAL; 723 return -EINVAL;
475 } 724 }
476 725
726 if (g2d_check_space(ctx, 12 + scale * 3 + negative + repeat_pad, 2))
727 return -ENOSPC;
728
729 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
730 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
731 g2d_add_base_addr(ctx, dst, g2d_dst);
732 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
733
734 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
735 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
736
737 g2d_add_cmd(ctx, SRC_REPEAT_MODE_REG, src->repeat_mode);
738 if (repeat_pad)
739 g2d_add_cmd(ctx, SRC_PAD_VALUE_REG, dst->color);
740
741 g2d_add_base_addr(ctx, src, g2d_src);
742 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
743
744 rop4.val = 0;
745 rop4.data.unmasked_rop3 = G2D_ROP3_SRC;
746
477 if (negative) { 747 if (negative) {
478 g2d_add_cmd(ctx, BG_COLOR_REG, 0x00FFFFFF); 748 g2d_add_cmd(ctx, BG_COLOR_REG, 0x00FFFFFF);
479 rop4.val = 0; 749 rop4.data.unmasked_rop3 ^= G2D_ROP3_DST;
480 rop4.data.unmasked_rop3 = G2D_ROP3_SRC^G2D_ROP3_DST;
481 g2d_add_cmd(ctx, ROP4_REG, rop4.val);
482 } else {
483 rop4.val = 0;
484 rop4.data.unmasked_rop3 = G2D_ROP3_SRC;
485 g2d_add_cmd(ctx, ROP4_REG, rop4.val);
486 } 750 }
487 751
752 g2d_add_cmd(ctx, ROP4_REG, rop4.val);
753
488 if (scale) { 754 if (scale) {
489 g2d_add_cmd(ctx, SRC_SCALE_CTRL_REG, G2D_SCALE_MODE_BILINEAR); 755 g2d_add_cmd(ctx, SRC_SCALE_CTRL_REG, G2D_SCALE_MODE_BILINEAR);
490 g2d_add_cmd(ctx, SRC_XSCALE_REG, G2D_DOUBLE_TO_FIXED(scale_x)); 756 g2d_add_cmd(ctx, SRC_XSCALE_REG, scale_x);
491 g2d_add_cmd(ctx, SRC_YSCALE_REG, G2D_DOUBLE_TO_FIXED(scale_y)); 757 g2d_add_cmd(ctx, SRC_YSCALE_REG, scale_y);
492 } 758 }
493 759
494 pt.val = 0;
495 pt.data.x = src_x; 760 pt.data.x = src_x;
496 pt.data.y = src_y; 761 pt.data.y = src_y;
497 g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val); 762 g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val);
498 pt.val = 0;
499 pt.data.x = src_x + src_w; 763 pt.data.x = src_x + src_w;
500 pt.data.y = src_y + src_h; 764 pt.data.y = src_y + src_h;
501 g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val); 765 g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val);
502 766
503 pt.val = 0;
504 pt.data.x = dst_x; 767 pt.data.x = dst_x;
505 pt.data.y = dst_y; 768 pt.data.y = dst_y;
506 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val); 769 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val);
507 pt.val = 0;
508 pt.data.x = dst_x + dst_w; 770 pt.data.x = dst_x + dst_w;
509 pt.data.y = dst_y + dst_h; 771 pt.data.y = dst_y + dst_h;
510 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val); 772 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val);
511 773
512 g2d_flush(ctx); 774 return g2d_flush(ctx);
513
514 return 0;
515} 775}
516 776
517/** 777/**
518 * g2d_blend - blend image data in source and destion buffers 778 * g2d_blend - blend image data in source and destination buffers.
519 * 779 *
520 * @ctx: a pointer to g2d_context structure. 780 * @ctx: a pointer to g2d_context structure.
521 * @src: a pointer to g2d_image structure including image and buffer 781 * @src: a pointer to g2d_image structure including image and buffer
@@ -530,7 +790,7 @@ g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
530 * @h: height value to source and destination buffer. 790 * @h: height value to source and destination buffer.
531 * @op: blend operation type. 791 * @op: blend operation type.
532 */ 792 */
533drm_public int 793int
534g2d_blend(struct g2d_context *ctx, struct g2d_image *src, 794g2d_blend(struct g2d_context *ctx, struct g2d_image *src,
535 struct g2d_image *dst, unsigned int src_x, 795 struct g2d_image *dst, unsigned int src_x,
536 unsigned int src_y, unsigned int dst_x, unsigned int dst_y, 796 unsigned int src_y, unsigned int dst_x, unsigned int dst_y,
@@ -539,7 +799,45 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src,
539 union g2d_point_val pt; 799 union g2d_point_val pt;
540 union g2d_bitblt_cmd_val bitblt; 800 union g2d_bitblt_cmd_val bitblt;
541 union g2d_blend_func_val blend; 801 union g2d_blend_func_val blend;
542 unsigned int src_w = 0, src_h = 0, dst_w = 0, dst_h = 0; 802 unsigned int gem_space;
803 unsigned int src_w, src_h, dst_w, dst_h;
804
805 src_w = w;
806 src_h = h;
807 if (src_x + w > src->width)
808 src_w = src->width - src_x;
809 if (src_y + h > src->height)
810 src_h = src->height - src_y;
811
812 dst_w = w;
813 dst_h = h;
814 if (dst_x + w > dst->width)
815 dst_w = dst->width - dst_x;
816 if (dst_y + h > dst->height)
817 dst_h = dst->height - dst_y;
818
819 w = MIN(src_w, dst_w);
820 h = MIN(src_h, dst_h);
821
822 if (w <= 0 || h <= 0) {
823 fprintf(stderr, MSG_PREFIX "invalid width or height.\n");
824 return -EINVAL;
825 }
826
827 if (!g2d_validate_select_mode(src->select_mode)) {
828 fprintf(stderr , MSG_PREFIX "invalid select mode for source.\n");
829 return -EINVAL;
830 }
831
832 if (!g2d_validate_blending_op(op)) {
833 fprintf(stderr , MSG_PREFIX "unsupported blending operation.\n");
834 return -EINVAL;
835 }
836
837 gem_space = src->select_mode == G2D_SELECT_MODE_NORMAL ? 2 : 1;
838
839 if (g2d_check_space(ctx, 12, gem_space))
840 return -ENOSPC;
543 841
544 bitblt.val = 0; 842 bitblt.val = 0;
545 blend.val = 0; 843 blend.val = 0;
@@ -550,12 +848,7 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src,
550 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_NORMAL); 848 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_NORMAL);
551 849
552 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode); 850 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
553 if (dst->buf_type == G2D_IMGBUF_USERPTR) 851 g2d_add_base_addr(ctx, dst, g2d_dst);
554 g2d_add_cmd(ctx, DST_BASE_ADDR_REG | G2D_BUF_USERPTR,
555 (unsigned long)&dst->user_ptr[0]);
556 else
557 g2d_add_cmd(ctx, DST_BASE_ADDR_REG, dst->bo[0]);
558
559 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride); 852 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
560 853
561 g2d_add_cmd(ctx, SRC_SELECT_REG, src->select_mode); 854 g2d_add_cmd(ctx, SRC_SELECT_REG, src->select_mode);
@@ -563,12 +856,7 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src,
563 856
564 switch (src->select_mode) { 857 switch (src->select_mode) {
565 case G2D_SELECT_MODE_NORMAL: 858 case G2D_SELECT_MODE_NORMAL:
566 if (src->buf_type == G2D_IMGBUF_USERPTR) 859 g2d_add_base_addr(ctx, src, g2d_src);
567 g2d_add_cmd(ctx, SRC_BASE_ADDR_REG | G2D_BUF_USERPTR,
568 (unsigned long)&src->user_ptr[0]);
569 else
570 g2d_add_cmd(ctx, SRC_BASE_ADDR_REG, src->bo[0]);
571
572 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride); 860 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
573 break; 861 break;
574 case G2D_SELECT_MODE_FGCOLOR: 862 case G2D_SELECT_MODE_FGCOLOR:
@@ -577,59 +865,151 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src,
577 case G2D_SELECT_MODE_BGCOLOR: 865 case G2D_SELECT_MODE_BGCOLOR:
578 g2d_add_cmd(ctx, BG_COLOR_REG, src->color); 866 g2d_add_cmd(ctx, BG_COLOR_REG, src->color);
579 break; 867 break;
580 default:
581 fprintf(stderr , "failed to set src.\n");
582 return -EINVAL;
583 } 868 }
584 869
585 src_w = w; 870 bitblt.data.alpha_blend_mode = G2D_ALPHA_BLEND_MODE_ENABLE;
586 src_h = h; 871 blend.val = g2d_get_blend_op(op);
587 if (src_x + w > src->width) 872 g2d_add_cmd(ctx, BITBLT_COMMAND_REG, bitblt.val);
873 g2d_add_cmd(ctx, BLEND_FUNCTION_REG, blend.val);
874
875 pt.data.x = src_x;
876 pt.data.y = src_y;
877 g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val);
878 pt.data.x = src_x + w;
879 pt.data.y = src_y + h;
880 g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val);
881
882 pt.data.x = dst_x;
883 pt.data.y = dst_y;
884 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val);
885 pt.data.x = dst_x + w;
886 pt.data.y = dst_y + h;
887 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val);
888
889 return g2d_flush(ctx);
890}
891
892/**
893 * g2d_scale_and_blend - apply scaling to source buffer and then blend to destination buffer
894 *
895 * @ctx: a pointer to g2d_context structure.
896 * @src: a pointer to g2d_image structure including image and buffer
897 * information to source.
898 * @dst: a pointer to g2d_image structure including image and buffer
899 * information to destination.
900 * @src_x: x start position to source buffer.
901 * @src_y: y start position to source buffer.
902 * @src_w: width value to source buffer.
903 * @src_h: height value to source buffer.
904 * @dst_x: x start position to destination buffer.
905 * @dst_y: y start position to destination buffer.
906 * @dst_w: width value to destination buffer.
907 * @dst_h: height value to destination buffer.
908 * @op: blend operation type.
909 */
910int
911g2d_scale_and_blend(struct g2d_context *ctx, struct g2d_image *src,
912 struct g2d_image *dst, unsigned int src_x, unsigned int src_y,
913 unsigned int src_w, unsigned int src_h, unsigned int dst_x,
914 unsigned int dst_y, unsigned int dst_w, unsigned int dst_h,
915 enum e_g2d_op op)
916{
917 union g2d_point_val pt;
918 union g2d_bitblt_cmd_val bitblt;
919 union g2d_blend_func_val blend;
920 unsigned int scale, gem_space;
921 unsigned int scale_x, scale_y;
922
923 if (src_w == dst_w && src_h == dst_h)
924 scale = 0;
925 else {
926 scale = 1;
927 scale_x = g2d_get_scaling(src_w, dst_w);
928 scale_y = g2d_get_scaling(src_h, dst_h);
929 }
930
931 if (src_x + src_w > src->width)
588 src_w = src->width - src_x; 932 src_w = src->width - src_x;
589 if (src_y + h > src->height) 933 if (src_y + src_h > src->height)
590 src_h = src->height - src_y; 934 src_h = src->height - src_y;
591 935
592 dst_w = w; 936 if (dst_x + dst_w > dst->width)
593 dst_h = h;
594 if (dst_x + w > dst->width)
595 dst_w = dst->width - dst_x; 937 dst_w = dst->width - dst_x;
596 if (dst_y + h > dst->height) 938 if (dst_y + dst_h > dst->height)
597 dst_h = dst->height - dst_y; 939 dst_h = dst->height - dst_y;
598 940
599 w = MIN(src_w, dst_w); 941 if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) {
600 h = MIN(src_h, dst_h); 942 fprintf(stderr, MSG_PREFIX "invalid width or height.\n");
943 return -EINVAL;
944 }
601 945
602 if (w <= 0 || h <= 0) { 946 if (!g2d_validate_select_mode(src->select_mode)) {
603 fprintf(stderr, "invalid width or height.\n"); 947 fprintf(stderr , MSG_PREFIX "invalid select mode for source.\n");
604 g2d_reset(ctx);
605 return -EINVAL; 948 return -EINVAL;
606 } 949 }
607 950
951 if (!g2d_validate_blending_op(op)) {
952 fprintf(stderr , MSG_PREFIX "unsupported blending operation.\n");
953 return -EINVAL;
954 }
955
956 gem_space = src->select_mode == G2D_SELECT_MODE_NORMAL ? 2 : 1;
957
958 if (g2d_check_space(ctx, 12 + scale * 3, gem_space))
959 return -ENOSPC;
960
961 bitblt.val = 0;
962 blend.val = 0;
963
964 if (op == G2D_OP_SRC || op == G2D_OP_CLEAR)
965 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
966 else
967 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_NORMAL);
968
969 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
970 g2d_add_base_addr(ctx, dst, g2d_dst);
971 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
972
973 g2d_add_cmd(ctx, SRC_SELECT_REG, src->select_mode);
974 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
975
976 switch (src->select_mode) {
977 case G2D_SELECT_MODE_NORMAL:
978 g2d_add_base_addr(ctx, src, g2d_src);
979 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
980 break;
981 case G2D_SELECT_MODE_FGCOLOR:
982 g2d_add_cmd(ctx, FG_COLOR_REG, src->color);
983 break;
984 case G2D_SELECT_MODE_BGCOLOR:
985 g2d_add_cmd(ctx, BG_COLOR_REG, src->color);
986 break;
987 }
988
989 if (scale) {
990 g2d_add_cmd(ctx, SRC_SCALE_CTRL_REG, G2D_SCALE_MODE_BILINEAR);
991 g2d_add_cmd(ctx, SRC_XSCALE_REG, scale_x);
992 g2d_add_cmd(ctx, SRC_YSCALE_REG, scale_y);
993 }
994
608 bitblt.data.alpha_blend_mode = G2D_ALPHA_BLEND_MODE_ENABLE; 995 bitblt.data.alpha_blend_mode = G2D_ALPHA_BLEND_MODE_ENABLE;
609 blend.val = g2d_get_blend_op(op); 996 blend.val = g2d_get_blend_op(op);
610 g2d_add_cmd(ctx, BITBLT_COMMAND_REG, bitblt.val); 997 g2d_add_cmd(ctx, BITBLT_COMMAND_REG, bitblt.val);
611 g2d_add_cmd(ctx, BLEND_FUNCTION_REG, blend.val); 998 g2d_add_cmd(ctx, BLEND_FUNCTION_REG, blend.val);
612 999
613 pt.val = 0;
614 pt.data.x = src_x; 1000 pt.data.x = src_x;
615 pt.data.y = src_y; 1001 pt.data.y = src_y;
616 g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val); 1002 g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val);
617 pt.val = 0; 1003 pt.data.x = src_x + src_w;
618 pt.data.x = src_x + w; 1004 pt.data.y = src_y + src_h;
619 pt.data.y = src_y + h;
620 g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val); 1005 g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val);
621 1006
622 pt.val = 0;
623 pt.data.x = dst_x; 1007 pt.data.x = dst_x;
624 pt.data.y = dst_y; 1008 pt.data.y = dst_y;
625 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val); 1009 g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val);
626 pt.val = 0; 1010 pt.data.x = dst_x + dst_w;
627 pt.data.x = dst_x + w; 1011 pt.data.y = dst_y + dst_h;
628 pt.data.y = dst_y + h;
629 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val); 1012 g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val);
630 1013
631 g2d_flush(ctx); 1014 return g2d_flush(ctx);
632
633 return 0;
634} 1015}
635
diff --git a/exynos/fimg2d.h b/exynos/exynos_fimg2d.h
index 4785e2f0..a825c683 100644
--- a/exynos/fimg2d.h
+++ b/exynos/exynos_fimg2d.h
@@ -13,20 +13,8 @@
13#ifndef _FIMG2D_H_ 13#ifndef _FIMG2D_H_
14#define _FIMG2D_H_ 14#define _FIMG2D_H_
15 15
16#ifndef TRUE
17#define TRUE 0
18#endif
19#ifndef FALSE
20#define FALSE -1
21#endif
22
23#define G2D_MAX_CMD_NR 64
24#define G2D_MAX_GEM_CMD_NR 64
25#define G2D_MAX_CMD_LIST_NR 64
26#define G2D_PLANE_MAX_NR 2 16#define G2D_PLANE_MAX_NR 2
27 17
28#define G2D_DOUBLE_TO_FIXED(d) ((unsigned int)((d) * 65536.0))
29
30enum e_g2d_color_mode { 18enum e_g2d_color_mode {
31 /* COLOR FORMAT */ 19 /* COLOR FORMAT */
32 G2D_COLOR_FMT_XRGB8888, 20 G2D_COLOR_FMT_XRGB8888,
@@ -151,6 +139,7 @@ enum e_g2d_op {
151 G2D_OP_SRC = 0x01, 139 G2D_OP_SRC = 0x01,
152 G2D_OP_DST = 0x02, 140 G2D_OP_DST = 0x02,
153 G2D_OP_OVER = 0x03, 141 G2D_OP_OVER = 0x03,
142 G2D_OP_INTERPOLATE = 0x04,
154 G2D_OP_DISJOINT_CLEAR = 0x10, 143 G2D_OP_DISJOINT_CLEAR = 0x10,
155 G2D_OP_DISJOINT_SRC = 0x11, 144 G2D_OP_DISJOINT_SRC = 0x11,
156 G2D_OP_DISJOINT_DST = 0x12, 145 G2D_OP_DISJOINT_DST = 0x12,
@@ -159,6 +148,12 @@ enum e_g2d_op {
159 G2D_OP_CONJOINT_DST = 0x22, 148 G2D_OP_CONJOINT_DST = 0x22,
160}; 149};
161 150
151/*
152 * The G2D_COEFF_MODE_DST_{COLOR,ALPHA} modes both use the ALPHA_REG(0x618)
153 * register. The registers fields are as follows:
154 * bits 31:8 = color value (RGB order)
155 * bits 7:0 = alpha value
156 */
162enum e_g2d_coeff_mode { 157enum e_g2d_coeff_mode {
163 G2D_COEFF_MODE_ONE, 158 G2D_COEFF_MODE_ONE,
164 G2D_COEFF_MODE_ZERO, 159 G2D_COEFF_MODE_ZERO,
@@ -168,7 +163,7 @@ enum e_g2d_coeff_mode {
168 G2D_COEFF_MODE_DST_COLOR, 163 G2D_COEFF_MODE_DST_COLOR,
169 /* Global Alpha : Set by ALPHA_REG(0x618) */ 164 /* Global Alpha : Set by ALPHA_REG(0x618) */
170 G2D_COEFF_MODE_GB_ALPHA, 165 G2D_COEFF_MODE_GB_ALPHA,
171 /* Global Alpha : Set by ALPHA_REG(0x618) */ 166 /* Global Color and Alpha : Set by ALPHA_REG(0x618) */
172 G2D_COEFF_MODE_GB_COLOR, 167 G2D_COEFF_MODE_GB_COLOR,
173 /* (1-SRC alpha)/DST Alpha */ 168 /* (1-SRC alpha)/DST Alpha */
174 G2D_COEFF_MODE_DISJOINT_S, 169 G2D_COEFF_MODE_DISJOINT_S,
@@ -291,19 +286,11 @@ struct g2d_image {
291 void *mapped_ptr[G2D_PLANE_MAX_NR]; 286 void *mapped_ptr[G2D_PLANE_MAX_NR];
292}; 287};
293 288
294struct g2d_context { 289struct g2d_context;
295 int fd;
296 unsigned int major;
297 unsigned int minor;
298 struct drm_exynos_g2d_cmd cmd[G2D_MAX_CMD_NR];
299 struct drm_exynos_g2d_cmd cmd_buf[G2D_MAX_GEM_CMD_NR];
300 unsigned int cmd_nr;
301 unsigned int cmd_buf_nr;
302 unsigned int cmdlist_nr;
303};
304 290
305struct g2d_context *g2d_init(int fd); 291struct g2d_context *g2d_init(int fd);
306void g2d_fini(struct g2d_context *ctx); 292void g2d_fini(struct g2d_context *ctx);
293void g2d_config_event(struct g2d_context *ctx, void *userdata);
307int g2d_exec(struct g2d_context *ctx); 294int g2d_exec(struct g2d_context *ctx);
308int g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img, 295int g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
309 unsigned int x, unsigned int y, unsigned int w, 296 unsigned int x, unsigned int y, unsigned int w,
@@ -312,6 +299,9 @@ int g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
312 struct g2d_image *dst, unsigned int src_x, 299 struct g2d_image *dst, unsigned int src_x,
313 unsigned int src_y, unsigned int dst_x, unsigned int dst_y, 300 unsigned int src_y, unsigned int dst_x, unsigned int dst_y,
314 unsigned int w, unsigned int h); 301 unsigned int w, unsigned int h);
302int g2d_move(struct g2d_context *ctx, struct g2d_image *img,
303 unsigned int src_x, unsigned int src_y, unsigned int dst_x,
304 unsigned dst_y, unsigned int w, unsigned int h);
315int g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src, 305int g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
316 struct g2d_image *dst, unsigned int src_x, 306 struct g2d_image *dst, unsigned int src_x,
317 unsigned int src_y, unsigned int src_w, 307 unsigned int src_y, unsigned int src_w,
@@ -322,4 +312,9 @@ int g2d_blend(struct g2d_context *ctx, struct g2d_image *src,
322 struct g2d_image *dst, unsigned int src_x, 312 struct g2d_image *dst, unsigned int src_x,
323 unsigned int src_y, unsigned int dst_x, unsigned int dst_y, 313 unsigned int src_y, unsigned int dst_x, unsigned int dst_y,
324 unsigned int w, unsigned int h, enum e_g2d_op op); 314 unsigned int w, unsigned int h, enum e_g2d_op op);
315int g2d_scale_and_blend(struct g2d_context *ctx, struct g2d_image *src,
316 struct g2d_image *dst, unsigned int src_x, unsigned int src_y,
317 unsigned int src_w, unsigned int src_h, unsigned int dst_x,
318 unsigned int dst_y, unsigned int dst_w, unsigned int dst_h,
319 enum e_g2d_op op);
325#endif /* _FIMG2D_H_ */ 320#endif /* _FIMG2D_H_ */
diff --git a/exynos/fimg2d_reg.h b/exynos/fimg2d_reg.h
index 57824882..07dd6349 100644
--- a/exynos/fimg2d_reg.h
+++ b/exynos/fimg2d_reg.h
@@ -15,7 +15,7 @@
15 15
16#define SOFT_RESET_REG (0x0000) 16#define SOFT_RESET_REG (0x0000)
17#define INTEN_REG (0x0004) 17#define INTEN_REG (0x0004)
18#define INTC_PEND_REG (0x000c) 18#define INTC_PEND_REG (0x000C)
19#define FIFO_STAT_REG (0x0010) 19#define FIFO_STAT_REG (0x0010)
20#define AXI_MODE_REG (0x001C) 20#define AXI_MODE_REG (0x001C)
21#define DMA_SFR_BASE_ADDR_REG (0x0080) 21#define DMA_SFR_BASE_ADDR_REG (0x0080)
diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in
index 5ce91186..ff1c4320 100644
--- a/exynos/libdrm_exynos.pc.in
+++ b/exynos/libdrm_exynos.pc.in
@@ -5,7 +5,7 @@ includedir=@includedir@
5 5
6Name: libdrm_exynos 6Name: libdrm_exynos
7Description: Userspace interface to exynos kernel DRM services 7Description: Userspace interface to exynos kernel DRM services
8Version: 0.6 8Version: 0.7
9Libs: -L${libdir} -ldrm_exynos 9Libs: -L${libdir} -ldrm_exynos
10Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos 10Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos
11Requires.private: libdrm 11Requires.private: libdrm
diff --git a/freedreno/Android.mk b/freedreno/Android.mk
index 7abaeb73..162c804a 100644
--- a/freedreno/Android.mk
+++ b/freedreno/Android.mk
@@ -13,7 +13,4 @@ LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_FREEDRENO_FILES))
13LOCAL_CFLAGS := \ 13LOCAL_CFLAGS := \
14 -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 14 -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1
15 15
16LOCAL_SHARED_LIBRARIES := \
17 libdrm
18
19include $(BUILD_SHARED_LIBRARY) 16include $(BUILD_SHARED_LIBRARY)
diff --git a/freedreno/Makefile.am b/freedreno/Makefile.am
index 4482afe2..9b7ec7df 100644
--- a/freedreno/Makefile.am
+++ b/freedreno/Makefile.am
@@ -3,16 +3,17 @@ include Makefile.sources
3 3
4AM_CFLAGS = \ 4AM_CFLAGS = \
5 $(WARN_CFLAGS) \ 5 $(WARN_CFLAGS) \
6 $(VISIBILITY_CFLAGS) \
7 -I$(top_srcdir) \ 6 -I$(top_srcdir) \
8 -I$(top_srcdir)/freedreno \
9 $(PTHREADSTUBS_CFLAGS) \ 7 $(PTHREADSTUBS_CFLAGS) \
10 -I$(top_srcdir)/include/drm 8 -I$(top_srcdir)/include/drm
11 9
12libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la 10libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la
13libdrm_freedreno_ladir = $(libdir) 11libdrm_freedreno_ladir = $(libdir)
14libdrm_freedreno_la_LDFLAGS = -version-number 1:0:0 -no-undefined 12libdrm_freedreno_la_LDFLAGS = -version-number 1:0:0 -no-undefined
15libdrm_freedreno_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ 13libdrm_freedreno_la_LIBADD = \
14 ../libdrm.la \
15 @PTHREADSTUBS_LIBS@ \
16 @CLOCK_LIB@
16 17
17libdrm_freedreno_la_SOURCES = $(LIBDRM_FREEDRENO_FILES) 18libdrm_freedreno_la_SOURCES = $(LIBDRM_FREEDRENO_FILES)
18if HAVE_FREEDRENO_KGSL 19if HAVE_FREEDRENO_KGSL
@@ -25,4 +26,5 @@ libdrm_freedrenocommoninclude_HEADERS = $(LIBDRM_FREEDRENO_H_FILES)
25pkgconfigdir = @pkgconfigdir@ 26pkgconfigdir = @pkgconfigdir@
26pkgconfig_DATA = libdrm_freedreno.pc 27pkgconfig_DATA = libdrm_freedreno.pc
27 28
28EXTRA_DIST = Android.mk 29TESTS = freedreno-symbol-check
30EXTRA_DIST = Android.mk $(TESTS)
diff --git a/freedreno/Makefile.sources b/freedreno/Makefile.sources
index c8c0244f..57a8bf1b 100644
--- a/freedreno/Makefile.sources
+++ b/freedreno/Makefile.sources
@@ -9,8 +9,7 @@ LIBDRM_FREEDRENO_FILES := \
9 msm/msm_drm.h \ 9 msm/msm_drm.h \
10 msm/msm_pipe.c \ 10 msm/msm_pipe.c \
11 msm/msm_priv.h \ 11 msm/msm_priv.h \
12 msm/msm_ringbuffer.c \ 12 msm/msm_ringbuffer.c
13 list.h
14 13
15LIBDRM_FREEDRENO_KGSL_FILES := \ 14LIBDRM_FREEDRENO_KGSL_FILES := \
16 kgsl/kgsl_bo.c \ 15 kgsl/kgsl_bo.c \
diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbol-check
new file mode 100755
index 00000000..f517b6e7
--- /dev/null
+++ b/freedreno/freedreno-symbol-check
@@ -0,0 +1,54 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.sources/LIBDRM_FREEDRENO_H_FILES
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13fd_bo_cpu_fini
14fd_bo_cpu_prep
15fd_bo_del
16fd_bo_dmabuf
17fd_bo_from_dmabuf
18fd_bo_from_fbdev
19fd_bo_from_handle
20fd_bo_from_name
21fd_bo_get_name
22fd_bo_handle
23fd_bo_map
24fd_bo_new
25fd_bo_ref
26fd_bo_size
27fd_device_del
28fd_device_fd
29fd_device_new
30fd_device_new_dup
31fd_device_ref
32fd_pipe_del
33fd_pipe_get_param
34fd_pipe_new
35fd_pipe_wait
36fd_pipe_wait_timeout
37fd_ringbuffer_del
38fd_ringbuffer_emit_reloc_ring
39fd_ringbuffer_flush
40fd_ringbuffer_new
41fd_ringbuffer_reloc
42fd_ringbuffer_reset
43fd_ringbuffer_set_parent
44fd_ringbuffer_timestamp
45fd_ringmarker_del
46fd_ringmarker_dwords
47fd_ringmarker_flush
48fd_ringmarker_mark
49fd_ringmarker_new
50EOF
51done)
52
53test ! -n "$FUNCS" || echo $FUNCS
54test ! -n "$FUNCS"
diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c
index 9089c931..a23c65d0 100644
--- a/freedreno/freedreno_bo.c
+++ b/freedreno/freedreno_bo.c
@@ -52,6 +52,9 @@ static struct fd_bo * lookup_bo(void *tbl, uint32_t key)
52 if (!drmHashLookup(tbl, key, (void **)&bo)) { 52 if (!drmHashLookup(tbl, key, (void **)&bo)) {
53 /* found, incr refcnt and return: */ 53 /* found, incr refcnt and return: */
54 bo = fd_bo_ref(bo); 54 bo = fd_bo_ref(bo);
55
56 /* don't break the bucket if this bo was found in one */
57 list_delinit(&bo->list);
55 } 58 }
56 return bo; 59 return bo;
57} 60}
@@ -81,7 +84,7 @@ static struct fd_bo * bo_from_handle(struct fd_device *dev,
81} 84}
82 85
83/* Frees older cached buffers. Called under table_lock */ 86/* Frees older cached buffers. Called under table_lock */
84void fd_cleanup_bo_cache(struct fd_device *dev, time_t time) 87drm_private void fd_cleanup_bo_cache(struct fd_device *dev, time_t time)
85{ 88{
86 int i; 89 int i;
87 90
@@ -167,7 +170,7 @@ static struct fd_bo *find_in_bucket(struct fd_device *dev,
167} 170}
168 171
169 172
170drm_public struct fd_bo * 173struct fd_bo *
171fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) 174fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
172{ 175{
173 struct fd_bo *bo = NULL; 176 struct fd_bo *bo = NULL;
@@ -201,7 +204,7 @@ fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
201 return bo; 204 return bo;
202} 205}
203 206
204drm_public struct fd_bo * 207struct fd_bo *
205fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size) 208fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size)
206{ 209{
207 struct fd_bo *bo = NULL; 210 struct fd_bo *bo = NULL;
@@ -220,26 +223,36 @@ out_unlock:
220 return bo; 223 return bo;
221} 224}
222 225
223drm_public struct fd_bo * 226struct fd_bo *
224fd_bo_from_dmabuf(struct fd_device *dev, int fd) 227fd_bo_from_dmabuf(struct fd_device *dev, int fd)
225{ 228{
226 struct drm_prime_handle req = {
227 .fd = fd,
228 };
229 int ret, size; 229 int ret, size;
230 uint32_t handle;
231 struct fd_bo *bo;
230 232
231 ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req); 233 pthread_mutex_lock(&table_lock);
234 ret = drmPrimeFDToHandle(dev->fd, fd, &handle);
232 if (ret) { 235 if (ret) {
233 return NULL; 236 return NULL;
234 } 237 }
235 238
236 /* hmm, would be nice if we had a way to figure out the size.. */ 239 bo = lookup_bo(dev->handle_table, handle);
237 size = 0; 240 if (bo)
241 goto out_unlock;
242
243 /* lseek() to get bo size */
244 size = lseek(fd, 0, SEEK_END);
245 lseek(fd, 0, SEEK_CUR);
246
247 bo = bo_from_handle(dev, size, handle);
248
249out_unlock:
250 pthread_mutex_unlock(&table_lock);
238 251
239 return fd_bo_from_handle(dev, req.handle, size); 252 return bo;
240} 253}
241 254
242drm_public struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name) 255struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name)
243{ 256{
244 struct drm_gem_open req = { 257 struct drm_gem_open req = {
245 .name = name, 258 .name = name,
@@ -272,24 +285,19 @@ out_unlock:
272 return bo; 285 return bo;
273} 286}
274 287
275drm_public struct fd_bo * fd_bo_ref(struct fd_bo *bo) 288struct fd_bo * fd_bo_ref(struct fd_bo *bo)
276{ 289{
277 atomic_inc(&bo->refcnt); 290 atomic_inc(&bo->refcnt);
278 return bo; 291 return bo;
279} 292}
280 293
281drm_public void fd_bo_del(struct fd_bo *bo) 294void fd_bo_del(struct fd_bo *bo)
282{ 295{
283 struct fd_device *dev = bo->dev; 296 struct fd_device *dev = bo->dev;
284 297
285 if (!atomic_dec_and_test(&bo->refcnt)) 298 if (!atomic_dec_and_test(&bo->refcnt))
286 return; 299 return;
287 300
288 if (bo->fd) {
289 close(bo->fd);
290 bo->fd = 0;
291 }
292
293 pthread_mutex_lock(&table_lock); 301 pthread_mutex_lock(&table_lock);
294 302
295 if (bo->bo_reuse) { 303 if (bo->bo_reuse) {
@@ -342,7 +350,7 @@ static void bo_del(struct fd_bo *bo)
342 bo->funcs->destroy(bo); 350 bo->funcs->destroy(bo);
343} 351}
344 352
345drm_public int fd_bo_get_name(struct fd_bo *bo, uint32_t *name) 353int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
346{ 354{
347 if (!bo->name) { 355 if (!bo->name) {
348 struct drm_gem_flink req = { 356 struct drm_gem_flink req = {
@@ -358,6 +366,7 @@ drm_public int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
358 pthread_mutex_lock(&table_lock); 366 pthread_mutex_lock(&table_lock);
359 set_name(bo, req.name); 367 set_name(bo, req.name);
360 pthread_mutex_unlock(&table_lock); 368 pthread_mutex_unlock(&table_lock);
369 bo->bo_reuse = 0;
361 } 370 }
362 371
363 *name = bo->name; 372 *name = bo->name;
@@ -365,36 +374,33 @@ drm_public int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
365 return 0; 374 return 0;
366} 375}
367 376
368drm_public uint32_t fd_bo_handle(struct fd_bo *bo) 377uint32_t fd_bo_handle(struct fd_bo *bo)
369{ 378{
370 return bo->handle; 379 return bo->handle;
371} 380}
372 381
373drm_public int fd_bo_dmabuf(struct fd_bo *bo) 382int fd_bo_dmabuf(struct fd_bo *bo)
374{ 383{
375 if (!bo->fd) { 384 int ret, prime_fd;
376 struct drm_prime_handle req = {
377 .handle = bo->handle,
378 .flags = DRM_CLOEXEC,
379 };
380 int ret;
381 385
382 ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req); 386 ret = drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC,
383 if (ret) { 387 &prime_fd);
384 return ret; 388 if (ret) {
385 } 389 ERROR_MSG("failed to get dmabuf fd: %d", ret);
386 390 return ret;
387 bo->fd = req.fd;
388 } 391 }
389 return dup(bo->fd); 392
393 bo->bo_reuse = 0;
394
395 return prime_fd;
390} 396}
391 397
392drm_public uint32_t fd_bo_size(struct fd_bo *bo) 398uint32_t fd_bo_size(struct fd_bo *bo)
393{ 399{
394 return bo->size; 400 return bo->size;
395} 401}
396 402
397drm_public void * fd_bo_map(struct fd_bo *bo) 403void * fd_bo_map(struct fd_bo *bo)
398{ 404{
399 if (!bo->map) { 405 if (!bo->map) {
400 uint64_t offset; 406 uint64_t offset;
@@ -416,12 +422,12 @@ drm_public void * fd_bo_map(struct fd_bo *bo)
416} 422}
417 423
418/* a bit odd to take the pipe as an arg, but it's a, umm, quirk of kgsl.. */ 424/* a bit odd to take the pipe as an arg, but it's a, umm, quirk of kgsl.. */
419drm_public int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) 425int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
420{ 426{
421 return bo->funcs->cpu_prep(bo, pipe, op); 427 return bo->funcs->cpu_prep(bo, pipe, op);
422} 428}
423 429
424drm_public void fd_bo_cpu_fini(struct fd_bo *bo) 430void fd_bo_cpu_fini(struct fd_bo *bo)
425{ 431{
426 bo->funcs->cpu_fini(bo); 432 bo->funcs->cpu_fini(bo);
427} 433}
diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c
index e8b5f60f..ddb95455 100644
--- a/freedreno/freedreno_device.c
+++ b/freedreno/freedreno_device.c
@@ -80,7 +80,7 @@ init_cache_buckets(struct fd_device *dev)
80 } 80 }
81} 81}
82 82
83drm_public struct fd_device * fd_device_new(int fd) 83struct fd_device * fd_device_new(int fd)
84{ 84{
85 struct fd_device *dev; 85 struct fd_device *dev;
86 drmVersionPtr version; 86 drmVersionPtr version;
@@ -121,7 +121,7 @@ drm_public struct fd_device * fd_device_new(int fd)
121/* like fd_device_new() but creates it's own private dup() of the fd 121/* like fd_device_new() but creates it's own private dup() of the fd
122 * which is close()d when the device is finalized. 122 * which is close()d when the device is finalized.
123 */ 123 */
124drm_public struct fd_device * fd_device_new_dup(int fd) 124struct fd_device * fd_device_new_dup(int fd)
125{ 125{
126 struct fd_device *dev = fd_device_new(dup(fd)); 126 struct fd_device *dev = fd_device_new(dup(fd));
127 if (dev) 127 if (dev)
@@ -129,7 +129,7 @@ drm_public struct fd_device * fd_device_new_dup(int fd)
129 return dev; 129 return dev;
130} 130}
131 131
132drm_public struct fd_device * fd_device_ref(struct fd_device *dev) 132struct fd_device * fd_device_ref(struct fd_device *dev)
133{ 133{
134 atomic_inc(&dev->refcnt); 134 atomic_inc(&dev->refcnt);
135 return dev; 135 return dev;
@@ -145,14 +145,14 @@ static void fd_device_del_impl(struct fd_device *dev)
145 dev->funcs->destroy(dev); 145 dev->funcs->destroy(dev);
146} 146}
147 147
148void fd_device_del_locked(struct fd_device *dev) 148drm_private void fd_device_del_locked(struct fd_device *dev)
149{ 149{
150 if (!atomic_dec_and_test(&dev->refcnt)) 150 if (!atomic_dec_and_test(&dev->refcnt))
151 return; 151 return;
152 fd_device_del_impl(dev); 152 fd_device_del_impl(dev);
153} 153}
154 154
155drm_public void fd_device_del(struct fd_device *dev) 155void fd_device_del(struct fd_device *dev)
156{ 156{
157 if (!atomic_dec_and_test(&dev->refcnt)) 157 if (!atomic_dec_and_test(&dev->refcnt))
158 return; 158 return;
@@ -160,3 +160,8 @@ drm_public void fd_device_del(struct fd_device *dev)
160 fd_device_del_impl(dev); 160 fd_device_del_impl(dev);
161 pthread_mutex_unlock(&table_lock); 161 pthread_mutex_unlock(&table_lock);
162} 162}
163
164int fd_device_fd(struct fd_device *dev)
165{
166 return dev->fd;
167}
diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h
index 88fc03de..5547e943 100644
--- a/freedreno/freedreno_drmif.h
+++ b/freedreno/freedreno_drmif.h
@@ -76,6 +76,7 @@ struct fd_device * fd_device_new(int fd);
76struct fd_device * fd_device_new_dup(int fd); 76struct fd_device * fd_device_new_dup(int fd);
77struct fd_device * fd_device_ref(struct fd_device *dev); 77struct fd_device * fd_device_ref(struct fd_device *dev);
78void fd_device_del(struct fd_device *dev); 78void fd_device_del(struct fd_device *dev);
79int fd_device_fd(struct fd_device *dev);
79 80
80 81
81/* pipe functions: 82/* pipe functions:
@@ -86,6 +87,9 @@ void fd_pipe_del(struct fd_pipe *pipe);
86int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, 87int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
87 uint64_t *value); 88 uint64_t *value);
88int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp); 89int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp);
90/* timeout in nanosec */
91int fd_pipe_wait_timeout(struct fd_pipe *pipe, uint32_t timestamp,
92 uint64_t timeout);
89 93
90 94
91/* buffer-object functions: 95/* buffer-object functions:
diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c
index 54e957b5..4a756d70 100644
--- a/freedreno/freedreno_pipe.c
+++ b/freedreno/freedreno_pipe.c
@@ -33,7 +33,7 @@
33#include "freedreno_drmif.h" 33#include "freedreno_drmif.h"
34#include "freedreno_priv.h" 34#include "freedreno_priv.h"
35 35
36drm_public struct fd_pipe * 36struct fd_pipe *
37fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) 37fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
38{ 38{
39 struct fd_pipe *pipe = NULL; 39 struct fd_pipe *pipe = NULL;
@@ -59,18 +59,24 @@ fail:
59 return NULL; 59 return NULL;
60} 60}
61 61
62drm_public void fd_pipe_del(struct fd_pipe *pipe) 62void fd_pipe_del(struct fd_pipe *pipe)
63{ 63{
64 pipe->funcs->destroy(pipe); 64 pipe->funcs->destroy(pipe);
65} 65}
66 66
67drm_public int fd_pipe_get_param(struct fd_pipe *pipe, 67int fd_pipe_get_param(struct fd_pipe *pipe,
68 enum fd_param_id param, uint64_t *value) 68 enum fd_param_id param, uint64_t *value)
69{ 69{
70 return pipe->funcs->get_param(pipe, param, value); 70 return pipe->funcs->get_param(pipe, param, value);
71} 71}
72 72
73drm_public int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp) 73int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
74{ 74{
75 return pipe->funcs->wait(pipe, timestamp); 75 return fd_pipe_wait_timeout(pipe, timestamp, ~0);
76}
77
78int fd_pipe_wait_timeout(struct fd_pipe *pipe, uint32_t timestamp,
79 uint64_t timeout)
80{
81 return pipe->funcs->wait(pipe, timestamp, timeout);
76} 82}
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index 8e072d96..53817b19 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -44,11 +44,11 @@
44#include <stdio.h> 44#include <stdio.h>
45#include <assert.h> 45#include <assert.h>
46 46
47#include "libdrm.h" 47#include "libdrm_macros.h"
48#include "xf86drm.h" 48#include "xf86drm.h"
49#include "xf86atomic.h" 49#include "xf86atomic.h"
50 50
51#include "list.h" 51#include "util_double_list.h"
52 52
53#include "freedreno_drmif.h" 53#include "freedreno_drmif.h"
54#include "freedreno_ringbuffer.h" 54#include "freedreno_ringbuffer.h"
@@ -83,7 +83,7 @@ struct fd_device {
83 */ 83 */
84 void *handle_table, *name_table; 84 void *handle_table, *name_table;
85 85
86 struct fd_device_funcs *funcs; 86 const struct fd_device_funcs *funcs;
87 87
88 struct fd_bo_bucket cache_bucket[14 * 4]; 88 struct fd_bo_bucket cache_bucket[14 * 4];
89 int num_buckets; 89 int num_buckets;
@@ -92,22 +92,22 @@ struct fd_device {
92 int closefd; /* call close(fd) upon destruction */ 92 int closefd; /* call close(fd) upon destruction */
93}; 93};
94 94
95void fd_cleanup_bo_cache(struct fd_device *dev, time_t time); 95drm_private void fd_cleanup_bo_cache(struct fd_device *dev, time_t time);
96 96
97/* for where @table_lock is already held: */ 97/* for where @table_lock is already held: */
98void fd_device_del_locked(struct fd_device *dev); 98drm_private void fd_device_del_locked(struct fd_device *dev);
99 99
100struct fd_pipe_funcs { 100struct fd_pipe_funcs {
101 struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size); 101 struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size);
102 int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value); 102 int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value);
103 int (*wait)(struct fd_pipe *pipe, uint32_t timestamp); 103 int (*wait)(struct fd_pipe *pipe, uint32_t timestamp, uint64_t timeout);
104 void (*destroy)(struct fd_pipe *pipe); 104 void (*destroy)(struct fd_pipe *pipe);
105}; 105};
106 106
107struct fd_pipe { 107struct fd_pipe {
108 struct fd_device *dev; 108 struct fd_device *dev;
109 enum fd_pipe_id id; 109 enum fd_pipe_id id;
110 struct fd_pipe_funcs *funcs; 110 const struct fd_pipe_funcs *funcs;
111}; 111};
112 112
113struct fd_ringmarker { 113struct fd_ringmarker {
@@ -138,10 +138,9 @@ struct fd_bo {
138 uint32_t size; 138 uint32_t size;
139 uint32_t handle; 139 uint32_t handle;
140 uint32_t name; 140 uint32_t name;
141 int fd; /* dmabuf handle */
142 void *map; 141 void *map;
143 atomic_t refcnt; 142 atomic_t refcnt;
144 struct fd_bo_funcs *funcs; 143 const struct fd_bo_funcs *funcs;
145 144
146 int bo_reuse; 145 int bo_reuse;
147 struct list_head list; /* bucket-list entry */ 146 struct list_head list; /* bucket-list entry */
diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c
index c13dfe95..984da241 100644
--- a/freedreno/freedreno_ringbuffer.c
+++ b/freedreno/freedreno_ringbuffer.c
@@ -36,7 +36,7 @@
36#include "freedreno_priv.h" 36#include "freedreno_priv.h"
37#include "freedreno_ringbuffer.h" 37#include "freedreno_ringbuffer.h"
38 38
39drm_public struct fd_ringbuffer * 39struct fd_ringbuffer *
40fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size) 40fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
41{ 41{
42 struct fd_ringbuffer *ring; 42 struct fd_ringbuffer *ring;
@@ -55,7 +55,7 @@ fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
55 return ring; 55 return ring;
56} 56}
57 57
58drm_public void fd_ringbuffer_del(struct fd_ringbuffer *ring) 58void fd_ringbuffer_del(struct fd_ringbuffer *ring)
59{ 59{
60 ring->funcs->destroy(ring); 60 ring->funcs->destroy(ring);
61} 61}
@@ -64,13 +64,13 @@ drm_public void fd_ringbuffer_del(struct fd_ringbuffer *ring)
64 * the IB source) as it's parent before emitting reloc's, to ensure 64 * the IB source) as it's parent before emitting reloc's, to ensure
65 * the bookkeeping works out properly. 65 * the bookkeeping works out properly.
66 */ 66 */
67drm_public void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring, 67void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
68 struct fd_ringbuffer *parent) 68 struct fd_ringbuffer *parent)
69{ 69{
70 ring->parent = parent; 70 ring->parent = parent;
71} 71}
72 72
73drm_public void fd_ringbuffer_reset(struct fd_ringbuffer *ring) 73void fd_ringbuffer_reset(struct fd_ringbuffer *ring)
74{ 74{
75 uint32_t *start = ring->start; 75 uint32_t *start = ring->start;
76 if (ring->pipe->id == FD_PIPE_2D) 76 if (ring->pipe->id == FD_PIPE_2D)
@@ -81,23 +81,23 @@ drm_public void fd_ringbuffer_reset(struct fd_ringbuffer *ring)
81} 81}
82 82
83/* maybe get rid of this and use fd_ringmarker_flush() from DDX too? */ 83/* maybe get rid of this and use fd_ringmarker_flush() from DDX too? */
84drm_public int fd_ringbuffer_flush(struct fd_ringbuffer *ring) 84int fd_ringbuffer_flush(struct fd_ringbuffer *ring)
85{ 85{
86 return ring->funcs->flush(ring, ring->last_start); 86 return ring->funcs->flush(ring, ring->last_start);
87} 87}
88 88
89drm_public uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring) 89uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring)
90{ 90{
91 return ring->last_timestamp; 91 return ring->last_timestamp;
92} 92}
93 93
94drm_public void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, 94void fd_ringbuffer_reloc(struct fd_ringbuffer *ring,
95 const struct fd_reloc *reloc) 95 const struct fd_reloc *reloc)
96{ 96{
97 ring->funcs->emit_reloc(ring, reloc); 97 ring->funcs->emit_reloc(ring, reloc);
98} 98}
99 99
100drm_public void 100void
101fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, 101fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
102 struct fd_ringmarker *target, 102 struct fd_ringmarker *target,
103 struct fd_ringmarker *end) 103 struct fd_ringmarker *end)
@@ -106,7 +106,7 @@ fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
106 ring->funcs->emit_reloc_ring(ring, target, end); 106 ring->funcs->emit_reloc_ring(ring, target, end);
107} 107}
108 108
109drm_public struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring) 109struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring)
110{ 110{
111 struct fd_ringmarker *marker = NULL; 111 struct fd_ringmarker *marker = NULL;
112 112
@@ -123,23 +123,23 @@ drm_public struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring)
123 return marker; 123 return marker;
124} 124}
125 125
126drm_public void fd_ringmarker_del(struct fd_ringmarker *marker) 126void fd_ringmarker_del(struct fd_ringmarker *marker)
127{ 127{
128 free(marker); 128 free(marker);
129} 129}
130 130
131drm_public void fd_ringmarker_mark(struct fd_ringmarker *marker) 131void fd_ringmarker_mark(struct fd_ringmarker *marker)
132{ 132{
133 marker->cur = marker->ring->cur; 133 marker->cur = marker->ring->cur;
134} 134}
135 135
136drm_public uint32_t fd_ringmarker_dwords(struct fd_ringmarker *start, 136uint32_t fd_ringmarker_dwords(struct fd_ringmarker *start,
137 struct fd_ringmarker *end) 137 struct fd_ringmarker *end)
138{ 138{
139 return end->cur - start->cur; 139 return end->cur - start->cur;
140} 140}
141 141
142drm_public int fd_ringmarker_flush(struct fd_ringmarker *marker) 142int fd_ringmarker_flush(struct fd_ringmarker *marker)
143{ 143{
144 struct fd_ringbuffer *ring = marker->ring; 144 struct fd_ringbuffer *ring = marker->ring;
145 return ring->funcs->flush(ring, marker->cur); 145 return ring->funcs->flush(ring, marker->cur);
diff --git a/freedreno/freedreno_ringbuffer.h b/freedreno/freedreno_ringbuffer.h
index a5e1d032..578cdb24 100644
--- a/freedreno/freedreno_ringbuffer.h
+++ b/freedreno/freedreno_ringbuffer.h
@@ -44,7 +44,7 @@ struct fd_ringbuffer {
44 int size; 44 int size;
45 uint32_t *cur, *end, *start, *last_start; 45 uint32_t *cur, *end, *start, *last_start;
46 struct fd_pipe *pipe; 46 struct fd_pipe *pipe;
47 struct fd_ringbuffer_funcs *funcs; 47 const struct fd_ringbuffer_funcs *funcs;
48 uint32_t last_timestamp; 48 uint32_t last_timestamp;
49 struct fd_ringbuffer *parent; 49 struct fd_ringbuffer *parent;
50}; 50};
diff --git a/freedreno/kgsl/kgsl_bo.c b/freedreno/kgsl/kgsl_bo.c
index fab33500..2b45b5e2 100644
--- a/freedreno/kgsl/kgsl_bo.c
+++ b/freedreno/kgsl/kgsl_bo.c
@@ -123,7 +123,7 @@ static void kgsl_bo_destroy(struct fd_bo *bo)
123 123
124} 124}
125 125
126static struct fd_bo_funcs funcs = { 126static const struct fd_bo_funcs funcs = {
127 .offset = kgsl_bo_offset, 127 .offset = kgsl_bo_offset,
128 .cpu_prep = kgsl_bo_cpu_prep, 128 .cpu_prep = kgsl_bo_cpu_prep,
129 .cpu_fini = kgsl_bo_cpu_fini, 129 .cpu_fini = kgsl_bo_cpu_fini,
@@ -131,7 +131,7 @@ static struct fd_bo_funcs funcs = {
131}; 131};
132 132
133/* allocate a buffer handle: */ 133/* allocate a buffer handle: */
134int kgsl_bo_new_handle(struct fd_device *dev, 134drm_private int kgsl_bo_new_handle(struct fd_device *dev,
135 uint32_t size, uint32_t flags, uint32_t *handle) 135 uint32_t size, uint32_t flags, uint32_t *handle)
136{ 136{
137 struct drm_kgsl_gem_create req = { 137 struct drm_kgsl_gem_create req = {
@@ -155,7 +155,7 @@ int kgsl_bo_new_handle(struct fd_device *dev,
155} 155}
156 156
157/* allocate a new buffer object */ 157/* allocate a new buffer object */
158struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev, 158drm_private struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev,
159 uint32_t size, uint32_t handle) 159 uint32_t size, uint32_t handle)
160{ 160{
161 struct kgsl_bo *kgsl_bo; 161 struct kgsl_bo *kgsl_bo;
@@ -175,7 +175,7 @@ struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev,
175 return bo; 175 return bo;
176} 176}
177 177
178drm_public struct fd_bo * 178struct fd_bo *
179fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size) 179fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size)
180{ 180{
181 struct fd_bo *bo; 181 struct fd_bo *bo;
@@ -218,7 +218,7 @@ fail:
218 return NULL; 218 return NULL;
219} 219}
220 220
221uint32_t kgsl_bo_gpuaddr(struct kgsl_bo *kgsl_bo, uint32_t offset) 221drm_private uint32_t kgsl_bo_gpuaddr(struct kgsl_bo *kgsl_bo, uint32_t offset)
222{ 222{
223 struct fd_bo *bo = &kgsl_bo->base; 223 struct fd_bo *bo = &kgsl_bo->base;
224 if (!kgsl_bo->gpuaddr) { 224 if (!kgsl_bo->gpuaddr) {
@@ -267,7 +267,8 @@ uint32_t kgsl_bo_gpuaddr(struct kgsl_bo *kgsl_bo, uint32_t offset)
267 * _emit_reloc().. 267 * _emit_reloc()..
268 */ 268 */
269 269
270void kgsl_bo_set_timestamp(struct kgsl_bo *kgsl_bo, uint32_t timestamp) 270drm_private void kgsl_bo_set_timestamp(struct kgsl_bo *kgsl_bo,
271 uint32_t timestamp)
271{ 272{
272 struct fd_bo *bo = &kgsl_bo->base; 273 struct fd_bo *bo = &kgsl_bo->base;
273 if (bo->name) { 274 if (bo->name) {
@@ -285,7 +286,7 @@ void kgsl_bo_set_timestamp(struct kgsl_bo *kgsl_bo, uint32_t timestamp)
285 } 286 }
286} 287}
287 288
288uint32_t kgsl_bo_get_timestamp(struct kgsl_bo *kgsl_bo) 289drm_private uint32_t kgsl_bo_get_timestamp(struct kgsl_bo *kgsl_bo)
289{ 290{
290 struct fd_bo *bo = &kgsl_bo->base; 291 struct fd_bo *bo = &kgsl_bo->base;
291 uint32_t timestamp = 0; 292 uint32_t timestamp = 0;
diff --git a/freedreno/kgsl/kgsl_device.c b/freedreno/kgsl/kgsl_device.c
index 5f2dfea4..175e8378 100644
--- a/freedreno/kgsl/kgsl_device.c
+++ b/freedreno/kgsl/kgsl_device.c
@@ -42,14 +42,14 @@ static void kgsl_device_destroy(struct fd_device *dev)
42 free(kgsl_dev); 42 free(kgsl_dev);
43} 43}
44 44
45static struct fd_device_funcs funcs = { 45static const struct fd_device_funcs funcs = {
46 .bo_new_handle = kgsl_bo_new_handle, 46 .bo_new_handle = kgsl_bo_new_handle,
47 .bo_from_handle = kgsl_bo_from_handle, 47 .bo_from_handle = kgsl_bo_from_handle,
48 .pipe_new = kgsl_pipe_new, 48 .pipe_new = kgsl_pipe_new,
49 .destroy = kgsl_device_destroy, 49 .destroy = kgsl_device_destroy,
50}; 50};
51 51
52struct fd_device * kgsl_device_new(int fd) 52drm_private struct fd_device * kgsl_device_new(int fd)
53{ 53{
54 struct kgsl_device *kgsl_dev; 54 struct kgsl_device *kgsl_dev;
55 struct fd_device *dev; 55 struct fd_device *dev;
diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c
index 1a795ba3..58b3b4d5 100644
--- a/freedreno/kgsl/kgsl_pipe.c
+++ b/freedreno/kgsl/kgsl_pipe.c
@@ -56,7 +56,8 @@ static int kgsl_pipe_get_param(struct fd_pipe *pipe,
56 } 56 }
57} 57}
58 58
59static int kgsl_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp) 59static int kgsl_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
60 uint64_t timeout)
60{ 61{
61 struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe); 62 struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe);
62 struct kgsl_device_waittimestamp req = { 63 struct kgsl_device_waittimestamp req = {
@@ -75,7 +76,8 @@ static int kgsl_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
75 return ret; 76 return ret;
76} 77}
77 78
78int kgsl_pipe_timestamp(struct kgsl_pipe *kgsl_pipe, uint32_t *timestamp) 79drm_private int kgsl_pipe_timestamp(struct kgsl_pipe *kgsl_pipe,
80 uint32_t *timestamp)
79{ 81{
80 struct kgsl_cmdstream_readtimestamp req = { 82 struct kgsl_cmdstream_readtimestamp req = {
81 .type = KGSL_TIMESTAMP_RETIRED 83 .type = KGSL_TIMESTAMP_RETIRED
@@ -100,26 +102,26 @@ static void kgsl_pipe_destroy(struct fd_pipe *pipe)
100 if (kgsl_pipe->drawctxt_id) 102 if (kgsl_pipe->drawctxt_id)
101 ioctl(kgsl_pipe->fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &req); 103 ioctl(kgsl_pipe->fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &req);
102 104
103 if (kgsl_pipe->fd) 105 if (kgsl_pipe->fd >= 0)
104 close(kgsl_pipe->fd); 106 close(kgsl_pipe->fd);
105 107
106 free(kgsl_pipe); 108 free(kgsl_pipe);
107} 109}
108 110
109static struct fd_pipe_funcs funcs = { 111static const struct fd_pipe_funcs funcs = {
110 .ringbuffer_new = kgsl_ringbuffer_new, 112 .ringbuffer_new = kgsl_ringbuffer_new,
111 .get_param = kgsl_pipe_get_param, 113 .get_param = kgsl_pipe_get_param,
112 .wait = kgsl_pipe_wait, 114 .wait = kgsl_pipe_wait,
113 .destroy = kgsl_pipe_destroy, 115 .destroy = kgsl_pipe_destroy,
114}; 116};
115 117
116int is_kgsl_pipe(struct fd_pipe *pipe) 118drm_private int is_kgsl_pipe(struct fd_pipe *pipe)
117{ 119{
118 return pipe->funcs == &funcs; 120 return pipe->funcs == &funcs;
119} 121}
120 122
121/* add buffer to submit list when it is referenced in cmdstream: */ 123/* add buffer to submit list when it is referenced in cmdstream: */
122void kgsl_pipe_add_submit(struct kgsl_pipe *kgsl_pipe, 124drm_private void kgsl_pipe_add_submit(struct kgsl_pipe *kgsl_pipe,
123 struct kgsl_bo *kgsl_bo) 125 struct kgsl_bo *kgsl_bo)
124{ 126{
125 struct fd_pipe *pipe = &kgsl_pipe->base; 127 struct fd_pipe *pipe = &kgsl_pipe->base;
@@ -134,7 +136,7 @@ void kgsl_pipe_add_submit(struct kgsl_pipe *kgsl_pipe,
134} 136}
135 137
136/* prepare buffers on submit list before flush: */ 138/* prepare buffers on submit list before flush: */
137void kgsl_pipe_pre_submit(struct kgsl_pipe *kgsl_pipe) 139drm_private void kgsl_pipe_pre_submit(struct kgsl_pipe *kgsl_pipe)
138{ 140{
139 struct fd_pipe *pipe = &kgsl_pipe->base; 141 struct fd_pipe *pipe = &kgsl_pipe->base;
140 struct kgsl_bo *kgsl_bo = NULL; 142 struct kgsl_bo *kgsl_bo = NULL;
@@ -150,7 +152,8 @@ void kgsl_pipe_pre_submit(struct kgsl_pipe *kgsl_pipe)
150} 152}
151 153
152/* process buffers on submit list after flush: */ 154/* process buffers on submit list after flush: */
153void kgsl_pipe_post_submit(struct kgsl_pipe *kgsl_pipe, uint32_t timestamp) 155drm_private void kgsl_pipe_post_submit(struct kgsl_pipe *kgsl_pipe,
156 uint32_t timestamp)
154{ 157{
155 struct fd_pipe *pipe = &kgsl_pipe->base; 158 struct fd_pipe *pipe = &kgsl_pipe->base;
156 struct kgsl_bo *kgsl_bo = NULL, *tmp; 159 struct kgsl_bo *kgsl_bo = NULL, *tmp;
@@ -168,7 +171,8 @@ void kgsl_pipe_post_submit(struct kgsl_pipe *kgsl_pipe, uint32_t timestamp)
168 kgsl_pipe_process_pending(kgsl_pipe, timestamp); 171 kgsl_pipe_process_pending(kgsl_pipe, timestamp);
169} 172}
170 173
171void kgsl_pipe_process_pending(struct kgsl_pipe *kgsl_pipe, uint32_t timestamp) 174drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *kgsl_pipe,
175 uint32_t timestamp)
172{ 176{
173 struct fd_pipe *pipe = &kgsl_pipe->base; 177 struct fd_pipe *pipe = &kgsl_pipe->base;
174 struct kgsl_bo *kgsl_bo = NULL, *tmp; 178 struct kgsl_bo *kgsl_bo = NULL, *tmp;
@@ -201,7 +205,8 @@ static int getprop(int fd, enum kgsl_property_type type,
201 } } while (0) 205 } } while (0)
202 206
203 207
204struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, enum fd_pipe_id id) 208drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
209 enum fd_pipe_id id)
205{ 210{
206 static const char *paths[] = { 211 static const char *paths[] = {
207 [FD_PIPE_3D] = "/dev/kgsl-3d0", 212 [FD_PIPE_3D] = "/dev/kgsl-3d0",
diff --git a/freedreno/kgsl/kgsl_priv.h b/freedreno/kgsl/kgsl_priv.h
index 56dc21a5..6ab64965 100644
--- a/freedreno/kgsl/kgsl_priv.h
+++ b/freedreno/kgsl/kgsl_priv.h
@@ -73,7 +73,7 @@ static inline struct kgsl_pipe * to_kgsl_pipe(struct fd_pipe *x)
73 return (struct kgsl_pipe *)x; 73 return (struct kgsl_pipe *)x;
74} 74}
75 75
76int is_kgsl_pipe(struct fd_pipe *pipe); 76drm_private int is_kgsl_pipe(struct fd_pipe *pipe);
77 77
78struct kgsl_bo { 78struct kgsl_bo {
79 struct fd_bo base; 79 struct fd_bo base;
@@ -91,25 +91,30 @@ static inline struct kgsl_bo * to_kgsl_bo(struct fd_bo *x)
91} 91}
92 92
93 93
94struct fd_device * kgsl_device_new(int fd); 94drm_private struct fd_device * kgsl_device_new(int fd);
95 95
96int kgsl_pipe_timestamp(struct kgsl_pipe *kgsl_pipe, uint32_t *timestamp); 96drm_private int kgsl_pipe_timestamp(struct kgsl_pipe *kgsl_pipe,
97void kgsl_pipe_add_submit(struct kgsl_pipe *pipe, struct kgsl_bo *bo); 97 uint32_t *timestamp);
98void kgsl_pipe_pre_submit(struct kgsl_pipe *pipe); 98drm_private void kgsl_pipe_add_submit(struct kgsl_pipe *pipe,
99void kgsl_pipe_post_submit(struct kgsl_pipe *pipe, uint32_t timestamp); 99 struct kgsl_bo *bo);
100void kgsl_pipe_process_pending(struct kgsl_pipe *pipe, uint32_t timestamp); 100drm_private void kgsl_pipe_pre_submit(struct kgsl_pipe *pipe);
101struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, enum fd_pipe_id id); 101drm_private void kgsl_pipe_post_submit(struct kgsl_pipe *pipe,
102 uint32_t timestamp);
103drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe,
104 uint32_t timestamp);
105drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
106 enum fd_pipe_id id);
102 107
103struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, 108drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
104 uint32_t size); 109 uint32_t size);
105 110
106int kgsl_bo_new_handle(struct fd_device *dev, 111drm_private int kgsl_bo_new_handle(struct fd_device *dev,
107 uint32_t size, uint32_t flags, uint32_t *handle); 112 uint32_t size, uint32_t flags, uint32_t *handle);
108struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev, 113drm_private struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev,
109 uint32_t size, uint32_t handle); 114 uint32_t size, uint32_t handle);
110 115
111uint32_t kgsl_bo_gpuaddr(struct kgsl_bo *bo, uint32_t offset); 116drm_private uint32_t kgsl_bo_gpuaddr(struct kgsl_bo *bo, uint32_t offset);
112void kgsl_bo_set_timestamp(struct kgsl_bo *bo, uint32_t timestamp); 117drm_private void kgsl_bo_set_timestamp(struct kgsl_bo *bo, uint32_t timestamp);
113uint32_t kgsl_bo_get_timestamp(struct kgsl_bo *bo); 118drm_private uint32_t kgsl_bo_get_timestamp(struct kgsl_bo *bo);
114 119
115#endif /* KGSL_PRIV_H_ */ 120#endif /* KGSL_PRIV_H_ */
diff --git a/freedreno/kgsl/kgsl_ringbuffer.c b/freedreno/kgsl/kgsl_ringbuffer.c
index d1e8321e..6f68f2f3 100644
--- a/freedreno/kgsl/kgsl_ringbuffer.c
+++ b/freedreno/kgsl/kgsl_ringbuffer.c
@@ -191,7 +191,7 @@ static void kgsl_ringbuffer_destroy(struct fd_ringbuffer *ring)
191 free(kgsl_ring); 191 free(kgsl_ring);
192} 192}
193 193
194static struct fd_ringbuffer_funcs funcs = { 194static const struct fd_ringbuffer_funcs funcs = {
195 .hostptr = kgsl_ringbuffer_hostptr, 195 .hostptr = kgsl_ringbuffer_hostptr,
196 .flush = kgsl_ringbuffer_flush, 196 .flush = kgsl_ringbuffer_flush,
197 .emit_reloc = kgsl_ringbuffer_emit_reloc, 197 .emit_reloc = kgsl_ringbuffer_emit_reloc,
@@ -199,7 +199,7 @@ static struct fd_ringbuffer_funcs funcs = {
199 .destroy = kgsl_ringbuffer_destroy, 199 .destroy = kgsl_ringbuffer_destroy,
200}; 200};
201 201
202struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, 202drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
203 uint32_t size) 203 uint32_t size)
204{ 204{
205 struct kgsl_ringbuffer *kgsl_ring; 205 struct kgsl_ringbuffer *kgsl_ring;
diff --git a/freedreno/msm/msm_bo.c b/freedreno/msm/msm_bo.c
index 0cac1c60..cd05a6cd 100644
--- a/freedreno/msm/msm_bo.c
+++ b/freedreno/msm/msm_bo.c
@@ -75,7 +75,7 @@ static int msm_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
75 .op = op, 75 .op = op,
76 }; 76 };
77 77
78 get_abs_timeout(&req.timeout, 5000); 78 get_abs_timeout(&req.timeout, 5000000000);
79 79
80 return drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_PREP, &req, sizeof(req)); 80 return drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_PREP, &req, sizeof(req));
81} 81}
@@ -96,7 +96,7 @@ static void msm_bo_destroy(struct fd_bo *bo)
96 96
97} 97}
98 98
99static struct fd_bo_funcs funcs = { 99static const struct fd_bo_funcs funcs = {
100 .offset = msm_bo_offset, 100 .offset = msm_bo_offset,
101 .cpu_prep = msm_bo_cpu_prep, 101 .cpu_prep = msm_bo_cpu_prep,
102 .cpu_fini = msm_bo_cpu_fini, 102 .cpu_fini = msm_bo_cpu_fini,
@@ -104,7 +104,7 @@ static struct fd_bo_funcs funcs = {
104}; 104};
105 105
106/* allocate a buffer handle: */ 106/* allocate a buffer handle: */
107int msm_bo_new_handle(struct fd_device *dev, 107drm_private int msm_bo_new_handle(struct fd_device *dev,
108 uint32_t size, uint32_t flags, uint32_t *handle) 108 uint32_t size, uint32_t flags, uint32_t *handle)
109{ 109{
110 struct drm_msm_gem_new req = { 110 struct drm_msm_gem_new req = {
@@ -124,12 +124,11 @@ int msm_bo_new_handle(struct fd_device *dev,
124} 124}
125 125
126/* allocate a new buffer object */ 126/* allocate a new buffer object */
127struct fd_bo * msm_bo_from_handle(struct fd_device *dev, 127drm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev,
128 uint32_t size, uint32_t handle) 128 uint32_t size, uint32_t handle)
129{ 129{
130 struct msm_bo *msm_bo; 130 struct msm_bo *msm_bo;
131 struct fd_bo *bo; 131 struct fd_bo *bo;
132 unsigned i;
133 132
134 msm_bo = calloc(1, sizeof(*msm_bo)); 133 msm_bo = calloc(1, sizeof(*msm_bo));
135 if (!msm_bo) 134 if (!msm_bo)
@@ -138,8 +137,5 @@ struct fd_bo * msm_bo_from_handle(struct fd_device *dev,
138 bo = &msm_bo->base; 137 bo = &msm_bo->base;
139 bo->funcs = &funcs; 138 bo->funcs = &funcs;
140 139
141 for (i = 0; i < ARRAY_SIZE(msm_bo->list); i++)
142 list_inithead(&msm_bo->list[i]);
143
144 return bo; 140 return bo;
145} 141}
diff --git a/freedreno/msm/msm_device.c b/freedreno/msm/msm_device.c
index b9c5a3e3..25c097c2 100644
--- a/freedreno/msm/msm_device.c
+++ b/freedreno/msm/msm_device.c
@@ -42,14 +42,14 @@ static void msm_device_destroy(struct fd_device *dev)
42 free(msm_dev); 42 free(msm_dev);
43} 43}
44 44
45static struct fd_device_funcs funcs = { 45static const struct fd_device_funcs funcs = {
46 .bo_new_handle = msm_bo_new_handle, 46 .bo_new_handle = msm_bo_new_handle,
47 .bo_from_handle = msm_bo_from_handle, 47 .bo_from_handle = msm_bo_from_handle,
48 .pipe_new = msm_pipe_new, 48 .pipe_new = msm_pipe_new,
49 .destroy = msm_device_destroy, 49 .destroy = msm_device_destroy,
50}; 50};
51 51
52struct fd_device * msm_device_new(int fd) 52drm_private struct fd_device * msm_device_new(int fd)
53{ 53{
54 struct msm_device *msm_dev; 54 struct msm_device *msm_dev;
55 struct fd_device *dev; 55 struct fd_device *dev;
diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c
index 6955f2c9..aa0866b4 100644
--- a/freedreno/msm/msm_pipe.c
+++ b/freedreno/msm/msm_pipe.c
@@ -54,7 +54,8 @@ static int msm_pipe_get_param(struct fd_pipe *pipe,
54 } 54 }
55} 55}
56 56
57static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp) 57static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
58 uint64_t timeout)
58{ 59{
59 struct fd_device *dev = pipe->dev; 60 struct fd_device *dev = pipe->dev;
60 struct drm_msm_wait_fence req = { 61 struct drm_msm_wait_fence req = {
@@ -62,7 +63,7 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
62 }; 63 };
63 int ret; 64 int ret;
64 65
65 get_abs_timeout(&req.timeout, 5000); 66 get_abs_timeout(&req.timeout, timeout);
66 67
67 ret = drmCommandWrite(dev->fd, DRM_MSM_WAIT_FENCE, &req, sizeof(req)); 68 ret = drmCommandWrite(dev->fd, DRM_MSM_WAIT_FENCE, &req, sizeof(req));
68 if (ret) { 69 if (ret) {
@@ -79,7 +80,7 @@ static void msm_pipe_destroy(struct fd_pipe *pipe)
79 free(msm_pipe); 80 free(msm_pipe);
80} 81}
81 82
82static struct fd_pipe_funcs funcs = { 83static const struct fd_pipe_funcs funcs = {
83 .ringbuffer_new = msm_ringbuffer_new, 84 .ringbuffer_new = msm_ringbuffer_new,
84 .get_param = msm_pipe_get_param, 85 .get_param = msm_pipe_get_param,
85 .wait = msm_pipe_wait, 86 .wait = msm_pipe_wait,
@@ -103,7 +104,8 @@ static uint64_t get_param(struct fd_device *dev, uint32_t pipe, uint32_t param)
103 return req.value; 104 return req.value;
104} 105}
105 106
106struct fd_pipe * msm_pipe_new(struct fd_device *dev, enum fd_pipe_id id) 107drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
108 enum fd_pipe_id id)
107{ 109{
108 static const uint32_t pipe_id[] = { 110 static const uint32_t pipe_id[] = {
109 [FD_PIPE_3D] = MSM_PIPE_3D0, 111 [FD_PIPE_3D] = MSM_PIPE_3D0,
diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h
index 75ae883f..e499b3b8 100644
--- a/freedreno/msm/msm_priv.h
+++ b/freedreno/msm/msm_priv.h
@@ -46,7 +46,7 @@ static inline struct msm_device * to_msm_device(struct fd_device *x)
46 return (struct msm_device *)x; 46 return (struct msm_device *)x;
47} 47}
48 48
49struct fd_device * msm_device_new(int fd); 49drm_private struct fd_device * msm_device_new(int fd);
50 50
51struct msm_pipe { 51struct msm_pipe {
52 struct fd_pipe base; 52 struct fd_pipe base;
@@ -61,17 +61,29 @@ static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x)
61 return (struct msm_pipe *)x; 61 return (struct msm_pipe *)x;
62} 62}
63 63
64struct fd_pipe * msm_pipe_new(struct fd_device *dev, enum fd_pipe_id id); 64drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
65 enum fd_pipe_id id);
65 66
66struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, 67drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
67 uint32_t size); 68 uint32_t size);
68 69
69struct msm_bo { 70struct msm_bo {
70 struct fd_bo base; 71 struct fd_bo base;
71 uint64_t offset; 72 uint64_t offset;
72 uint64_t presumed; 73 uint64_t presumed;
73 uint32_t indexp1[FD_PIPE_MAX]; /* index plus 1 */ 74 /* in the common case, a bo won't be referenced by more than a single
74 struct list_head list[FD_PIPE_MAX]; 75 * (parent) ring[*]. So to avoid looping over all the bo's in the
76 * reloc table to find the idx of a bo that might already be in the
77 * table, we cache the idx in the bo. But in order to detect the
78 * slow-path where bo is ref'd in multiple rb's, we also must track
79 * the current_ring for which the idx is valid. See bo2idx().
80 *
81 * [*] in case multiple ringbuffers, ie. one toplevel and other rb(s)
82 * used for IB target(s), the toplevel rb is the parent which is
83 * tracking bo's for the submit
84 */
85 struct fd_ringbuffer *current_ring;
86 uint32_t idx;
75}; 87};
76 88
77static inline struct msm_bo * to_msm_bo(struct fd_bo *x) 89static inline struct msm_bo * to_msm_bo(struct fd_bo *x)
@@ -79,18 +91,18 @@ static inline struct msm_bo * to_msm_bo(struct fd_bo *x)
79 return (struct msm_bo *)x; 91 return (struct msm_bo *)x;
80} 92}
81 93
82int msm_bo_new_handle(struct fd_device *dev, 94drm_private int msm_bo_new_handle(struct fd_device *dev,
83 uint32_t size, uint32_t flags, uint32_t *handle); 95 uint32_t size, uint32_t flags, uint32_t *handle);
84struct fd_bo * msm_bo_from_handle(struct fd_device *dev, 96drm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev,
85 uint32_t size, uint32_t handle); 97 uint32_t size, uint32_t handle);
86 98
87static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint32_t ms) 99static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns)
88{ 100{
89 struct timespec t; 101 struct timespec t;
90 uint32_t s = ms / 1000; 102 uint32_t s = ns / 1000000000;
91 clock_gettime(CLOCK_MONOTONIC, &t); 103 clock_gettime(CLOCK_MONOTONIC, &t);
92 tv->tv_sec = t.tv_sec + s; 104 tv->tv_sec = t.tv_sec + s;
93 tv->tv_nsec = t.tv_nsec + ((ms - (s * 1000)) * 1000000); 105 tv->tv_nsec = t.tv_nsec + ns - (s * 1000000000);
94} 106}
95 107
96#endif /* MSM_PRIV_H_ */ 108#endif /* MSM_PRIV_H_ */
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index 6a4043fb..becf2458 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -31,6 +31,7 @@
31#endif 31#endif
32 32
33#include <assert.h> 33#include <assert.h>
34#include <inttypes.h>
34 35
35#include "freedreno_ringbuffer.h" 36#include "freedreno_ringbuffer.h"
36#include "msm_priv.h" 37#include "msm_priv.h"
@@ -39,23 +40,32 @@ struct msm_ringbuffer {
39 struct fd_ringbuffer base; 40 struct fd_ringbuffer base;
40 struct fd_bo *ring_bo; 41 struct fd_bo *ring_bo;
41 42
42 struct list_head submit_list; 43 /* submit ioctl related tables: */
44 struct {
45 /* bo's table: */
46 struct drm_msm_gem_submit_bo *bos;
47 uint32_t nr_bos, max_bos;
43 48
44 /* bo's table: */ 49 /* cmd's table: */
45 struct drm_msm_gem_submit_bo *bos; 50 struct drm_msm_gem_submit_cmd *cmds;
51 uint32_t nr_cmds, max_cmds;
52
53 /* reloc's table: */
54 struct drm_msm_gem_submit_reloc *relocs;
55 uint32_t nr_relocs, max_relocs;
56 } submit;
57
58 /* should have matching entries in submit.bos: */
59 struct fd_bo **bos;
46 uint32_t nr_bos, max_bos; 60 uint32_t nr_bos, max_bos;
47 61
48 /* cmd's table: */ 62 /* should have matching entries in submit.cmds: */
49 struct drm_msm_gem_submit_cmd *cmds;
50 uint32_t nr_cmds, max_cmds;
51 struct fd_ringbuffer **rings; 63 struct fd_ringbuffer **rings;
52 uint32_t nr_rings, max_rings; 64 uint32_t nr_rings, max_rings;
53
54 /* reloc's table: */
55 struct drm_msm_gem_submit_reloc *relocs;
56 uint32_t nr_relocs, max_relocs;
57}; 65};
58 66
67static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER;
68
59static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz) 69static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz)
60{ 70{
61 if ((nr + 1) > *max) { 71 if ((nr + 1) > *max) {
@@ -78,31 +88,51 @@ static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x)
78 return (struct msm_ringbuffer *)x; 88 return (struct msm_ringbuffer *)x;
79} 89}
80 90
91static uint32_t append_bo(struct fd_ringbuffer *ring, struct fd_bo *bo)
92{
93 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
94 uint32_t idx;
95
96 idx = APPEND(&msm_ring->submit, bos);
97 idx = APPEND(msm_ring, bos);
98
99 msm_ring->submit.bos[idx].flags = 0;
100 msm_ring->submit.bos[idx].handle = bo->handle;
101 msm_ring->submit.bos[idx].presumed = to_msm_bo(bo)->presumed;
102
103 msm_ring->bos[idx] = fd_bo_ref(bo);
104
105 return idx;
106}
107
81/* add (if needed) bo, return idx: */ 108/* add (if needed) bo, return idx: */
82static uint32_t bo2idx(struct fd_ringbuffer *ring, struct fd_bo *bo, uint32_t flags) 109static uint32_t bo2idx(struct fd_ringbuffer *ring, struct fd_bo *bo, uint32_t flags)
83{ 110{
84 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 111 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
85 struct msm_bo *msm_bo = to_msm_bo(bo); 112 struct msm_bo *msm_bo = to_msm_bo(bo);
86 int id = ring->pipe->id;
87 uint32_t idx; 113 uint32_t idx;
88 if (!msm_bo->indexp1[id]) { 114 pthread_mutex_lock(&idx_lock);
89 struct list_head *list = &msm_bo->list[id]; 115 if (!msm_bo->current_ring) {
90 idx = APPEND(msm_ring, bos); 116 idx = append_bo(ring, bo);
91 msm_ring->bos[idx].flags = 0; 117 msm_bo->current_ring = ring;
92 msm_ring->bos[idx].handle = bo->handle; 118 msm_bo->idx = idx;
93 msm_ring->bos[idx].presumed = msm_bo->presumed; 119 } else if (msm_bo->current_ring == ring) {
94 msm_bo->indexp1[id] = idx + 1; 120 idx = msm_bo->idx;
95
96 assert(LIST_IS_EMPTY(list));
97 fd_bo_ref(bo);
98 list_addtail(list, &msm_ring->submit_list);
99 } else { 121 } else {
100 idx = msm_bo->indexp1[id] - 1; 122 /* slow-path: */
123 for (idx = 0; idx < msm_ring->nr_bos; idx++)
124 if (msm_ring->bos[idx] == bo)
125 break;
126 if (idx == msm_ring->nr_bos) {
127 /* not found */
128 idx = append_bo(ring, bo);
129 }
101 } 130 }
131 pthread_mutex_unlock(&idx_lock);
102 if (flags & FD_RELOC_READ) 132 if (flags & FD_RELOC_READ)
103 msm_ring->bos[idx].flags |= MSM_SUBMIT_BO_READ; 133 msm_ring->submit.bos[idx].flags |= MSM_SUBMIT_BO_READ;
104 if (flags & FD_RELOC_WRITE) 134 if (flags & FD_RELOC_WRITE)
105 msm_ring->bos[idx].flags |= MSM_SUBMIT_BO_WRITE; 135 msm_ring->submit.bos[idx].flags |= MSM_SUBMIT_BO_WRITE;
106 return idx; 136 return idx;
107} 137}
108 138
@@ -110,7 +140,7 @@ static int check_cmd_bo(struct fd_ringbuffer *ring,
110 struct drm_msm_gem_submit_cmd *cmd, struct fd_bo *bo) 140 struct drm_msm_gem_submit_cmd *cmd, struct fd_bo *bo)
111{ 141{
112 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 142 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
113 return msm_ring->bos[cmd->submit_idx].handle == bo->handle; 143 return msm_ring->submit.bos[cmd->submit_idx].handle == bo->handle;
114} 144}
115 145
116static uint32_t offset_bytes(void *end, void *start) 146static uint32_t offset_bytes(void *end, void *start)
@@ -127,8 +157,8 @@ static struct drm_msm_gem_submit_cmd * get_cmd(struct fd_ringbuffer *ring,
127 uint32_t i; 157 uint32_t i;
128 158
129 /* figure out if we already have a cmd buf: */ 159 /* figure out if we already have a cmd buf: */
130 for (i = 0; i < msm_ring->nr_cmds; i++) { 160 for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
131 cmd = &msm_ring->cmds[i]; 161 cmd = &msm_ring->submit.cmds[i];
132 if ((cmd->submit_offset == submit_offset) && 162 if ((cmd->submit_offset == submit_offset) &&
133 (cmd->size == size) && 163 (cmd->size == size) &&
134 (cmd->type == type) && 164 (cmd->type == type) &&
@@ -139,10 +169,10 @@ static struct drm_msm_gem_submit_cmd * get_cmd(struct fd_ringbuffer *ring,
139 169
140 /* create cmd buf if not: */ 170 /* create cmd buf if not: */
141 if (!cmd) { 171 if (!cmd) {
142 uint32_t idx = APPEND(msm_ring, cmds); 172 uint32_t idx = APPEND(&msm_ring->submit, cmds);
143 APPEND(msm_ring, rings); 173 APPEND(msm_ring, rings);
144 msm_ring->rings[idx] = target_ring; 174 msm_ring->rings[idx] = target_ring;
145 cmd = &msm_ring->cmds[idx]; 175 cmd = &msm_ring->submit.cmds[idx];
146 cmd->type = type; 176 cmd->type = type;
147 cmd->submit_idx = bo2idx(ring, target_bo, FD_RELOC_READ); 177 cmd->submit_idx = bo2idx(ring, target_bo, FD_RELOC_READ);
148 cmd->submit_offset = submit_offset; 178 cmd->submit_offset = submit_offset;
@@ -165,8 +195,8 @@ static uint32_t find_next_reloc_idx(struct msm_ringbuffer *msm_ring,
165 uint32_t i; 195 uint32_t i;
166 196
167 /* a binary search would be more clever.. */ 197 /* a binary search would be more clever.. */
168 for (i = start; i < msm_ring->nr_relocs; i++) { 198 for (i = start; i < msm_ring->submit.nr_relocs; i++) {
169 struct drm_msm_gem_submit_reloc *reloc = &msm_ring->relocs[i]; 199 struct drm_msm_gem_submit_reloc *reloc = &msm_ring->submit.relocs[i];
170 if (reloc->submit_offset >= offset) 200 if (reloc->submit_offset >= offset)
171 return i; 201 return i;
172 } 202 }
@@ -180,13 +210,15 @@ static void flush_reset(struct fd_ringbuffer *ring)
180 unsigned i; 210 unsigned i;
181 211
182 /* for each of the cmd buffers, clear their reloc's: */ 212 /* for each of the cmd buffers, clear their reloc's: */
183 for (i = 0; i < msm_ring->nr_cmds; i++) { 213 for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
184 struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]); 214 struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]);
185 target_ring->nr_relocs = 0; 215 target_ring->submit.nr_relocs = 0;
186 } 216 }
187 217
188 msm_ring->nr_relocs = 0; 218 msm_ring->submit.nr_relocs = 0;
189 msm_ring->nr_cmds = 0; 219 msm_ring->submit.nr_cmds = 0;
220 msm_ring->submit.nr_bos = 0;
221 msm_ring->nr_rings = 0;
190 msm_ring->nr_bos = 0; 222 msm_ring->nr_bos = 0;
191} 223}
192 224
@@ -197,9 +229,8 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
197 struct drm_msm_gem_submit req = { 229 struct drm_msm_gem_submit req = {
198 .pipe = to_msm_pipe(ring->pipe)->pipe, 230 .pipe = to_msm_pipe(ring->pipe)->pipe,
199 }; 231 };
200 struct msm_bo *msm_bo = NULL, *tmp; 232 uint32_t i, j, submit_offset, size;
201 uint32_t i, submit_offset, size; 233 int ret;
202 int ret, id = ring->pipe->id;
203 234
204 submit_offset = offset_bytes(last_start, ring->start); 235 submit_offset = offset_bytes(last_start, ring->start);
205 size = offset_bytes(ring->cur, last_start); 236 size = offset_bytes(ring->cur, last_start);
@@ -207,40 +238,56 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
207 get_cmd(ring, ring, ring_bo, submit_offset, size, MSM_SUBMIT_CMD_BUF); 238 get_cmd(ring, ring, ring_bo, submit_offset, size, MSM_SUBMIT_CMD_BUF);
208 239
209 /* needs to be after get_cmd() as that could create bos/cmds table: */ 240 /* needs to be after get_cmd() as that could create bos/cmds table: */
210 req.bos = VOID2U64(msm_ring->bos), 241 req.bos = VOID2U64(msm_ring->submit.bos),
211 req.nr_bos = msm_ring->nr_bos; 242 req.nr_bos = msm_ring->submit.nr_bos;
212 req.cmds = VOID2U64(msm_ring->cmds), 243 req.cmds = VOID2U64(msm_ring->submit.cmds),
213 req.nr_cmds = msm_ring->nr_cmds; 244 req.nr_cmds = msm_ring->submit.nr_cmds;
214 245
215 /* for each of the cmd's fix up their reloc's: */ 246 /* for each of the cmd's fix up their reloc's: */
216 for (i = 0; i < msm_ring->nr_cmds; i++) { 247 for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
217 struct drm_msm_gem_submit_cmd *cmd = &msm_ring->cmds[i]; 248 struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i];
218 struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]); 249 struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]);
219 uint32_t a = find_next_reloc_idx(target_ring, 0, cmd->submit_offset); 250 uint32_t a = find_next_reloc_idx(target_ring, 0, cmd->submit_offset);
220 uint32_t b = find_next_reloc_idx(target_ring, a, cmd->submit_offset + cmd->size); 251 uint32_t b = find_next_reloc_idx(target_ring, a, cmd->submit_offset + cmd->size);
221 cmd->relocs = VOID2U64(&target_ring->relocs[a]); 252 cmd->relocs = VOID2U64(&target_ring->submit.relocs[a]);
222 cmd->nr_relocs = (b > a) ? b - a : 0; 253 cmd->nr_relocs = (b > a) ? b - a : 0;
223 } 254 }
224 255
225 DEBUG_MSG("nr_cmds=%u, nr_bos=%u\n", req.nr_cmds, req.nr_bos); 256 DEBUG_MSG("nr_cmds=%u, nr_bos=%u", req.nr_cmds, req.nr_bos);
226 257
227 ret = drmCommandWriteRead(ring->pipe->dev->fd, DRM_MSM_GEM_SUBMIT, 258 ret = drmCommandWriteRead(ring->pipe->dev->fd, DRM_MSM_GEM_SUBMIT,
228 &req, sizeof(req)); 259 &req, sizeof(req));
229 if (ret) { 260 if (ret) {
230 ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno)); 261 ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno));
262 ERROR_MSG(" pipe: %u", req.pipe);
263 for (i = 0; i < msm_ring->submit.nr_bos; i++) {
264 struct drm_msm_gem_submit_bo *bo = &msm_ring->submit.bos[i];
265 ERROR_MSG(" bos[%d]: handle=%u, flags=%x", i, bo->handle, bo->flags);
266 }
267 for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
268 struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i];
269 struct drm_msm_gem_submit_reloc *relocs = U642VOID(cmd->relocs);
270 ERROR_MSG(" cmd[%d]: type=%u, submit_idx=%u, submit_offset=%u, size=%u",
271 i, cmd->type, cmd->submit_idx, cmd->submit_offset, cmd->size);
272 for (j = 0; j < cmd->nr_relocs; j++) {
273 struct drm_msm_gem_submit_reloc *r = &relocs[j];
274 ERROR_MSG(" reloc[%d]: submit_offset=%u, or=%08x, shift=%d, reloc_idx=%u"
275 ", reloc_offset=%"PRIu64, j, r->submit_offset, r->or, r->shift,
276 r->reloc_idx, r->reloc_offset);
277 }
278 }
231 } else { 279 } else {
232 /* update timestamp on all rings associated with submit: */ 280 /* update timestamp on all rings associated with submit: */
233 for (i = 0; i < msm_ring->nr_cmds; i++) { 281 for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
234 struct fd_ringbuffer *target_ring = msm_ring->rings[i]; 282 struct fd_ringbuffer *target_ring = msm_ring->rings[i];
235 if (!ret) 283 if (!ret)
236 target_ring->last_timestamp = req.fence; 284 target_ring->last_timestamp = req.fence;
237 } 285 }
238 } 286 }
239 287
240 LIST_FOR_EACH_ENTRY_SAFE(msm_bo, tmp, &msm_ring->submit_list, list[id]) { 288 for (i = 0; i < msm_ring->nr_bos; i++) {
241 struct list_head *list = &msm_bo->list[id]; 289 struct msm_bo *msm_bo = to_msm_bo(msm_ring->bos[i]);
242 list_delinit(list); 290 msm_bo->current_ring = NULL;
243 msm_bo->indexp1[id] = 0;
244 fd_bo_del(&msm_bo->base); 291 fd_bo_del(&msm_bo->base);
245 } 292 }
246 293
@@ -261,10 +308,10 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
261 struct fd_ringbuffer *parent = ring->parent ? ring->parent : ring; 308 struct fd_ringbuffer *parent = ring->parent ? ring->parent : ring;
262 struct msm_bo *msm_bo = to_msm_bo(r->bo); 309 struct msm_bo *msm_bo = to_msm_bo(r->bo);
263 struct drm_msm_gem_submit_reloc *reloc; 310 struct drm_msm_gem_submit_reloc *reloc;
264 uint32_t idx = APPEND(msm_ring, relocs); 311 uint32_t idx = APPEND(&msm_ring->submit, relocs);
265 uint32_t addr; 312 uint32_t addr;
266 313
267 reloc = &msm_ring->relocs[idx]; 314 reloc = &msm_ring->submit.relocs[idx];
268 315
269 reloc->reloc_idx = bo2idx(parent, r->bo, r->flags); 316 reloc->reloc_idx = bo2idx(parent, r->bo, r->flags);
270 reloc->reloc_offset = r->offset; 317 reloc->reloc_offset = r->offset;
@@ -309,7 +356,7 @@ static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring)
309 free(msm_ring); 356 free(msm_ring);
310} 357}
311 358
312static struct fd_ringbuffer_funcs funcs = { 359static const struct fd_ringbuffer_funcs funcs = {
313 .hostptr = msm_ringbuffer_hostptr, 360 .hostptr = msm_ringbuffer_hostptr,
314 .flush = msm_ringbuffer_flush, 361 .flush = msm_ringbuffer_flush,
315 .reset = msm_ringbuffer_reset, 362 .reset = msm_ringbuffer_reset,
@@ -318,7 +365,7 @@ static struct fd_ringbuffer_funcs funcs = {
318 .destroy = msm_ringbuffer_destroy, 365 .destroy = msm_ringbuffer_destroy,
319}; 366};
320 367
321struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, 368drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
322 uint32_t size) 369 uint32_t size)
323{ 370{
324 struct msm_ringbuffer *msm_ring; 371 struct msm_ringbuffer *msm_ring;
@@ -333,8 +380,6 @@ struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
333 ring = &msm_ring->base; 380 ring = &msm_ring->base;
334 ring->funcs = &funcs; 381 ring->funcs = &funcs;
335 382
336 list_inithead(&msm_ring->submit_list);
337
338 msm_ring->ring_bo = fd_bo_new(pipe->dev, size, 0); 383 msm_ring->ring_bo = fd_bo_new(pipe->dev, size, 0);
339 if (!msm_ring->ring_bo) { 384 if (!msm_ring->ring_bo) {
340 ERROR_MSG("ringbuffer allocation failed"); 385 ERROR_MSG("ringbuffer allocation failed");
diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
new file mode 100644
index 00000000..fbdd1185
--- /dev/null
+++ b/include/drm/amdgpu_drm.h
@@ -0,0 +1,645 @@
1/* amdgpu_drm.h -- Public header for the amdgpu driver -*- linux-c -*-
2 *
3 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Copyright 2014 Advanced Micro Devices, Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Kevin E. Martin <martin@valinux.com>
28 * Gareth Hughes <gareth@valinux.com>
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32#ifndef __AMDGPU_DRM_H__
33#define __AMDGPU_DRM_H__
34
35#include "drm.h"
36
37#define DRM_AMDGPU_GEM_CREATE 0x00
38#define DRM_AMDGPU_GEM_MMAP 0x01
39#define DRM_AMDGPU_CTX 0x02
40#define DRM_AMDGPU_BO_LIST 0x03
41#define DRM_AMDGPU_CS 0x04
42#define DRM_AMDGPU_INFO 0x05
43#define DRM_AMDGPU_GEM_METADATA 0x06
44#define DRM_AMDGPU_GEM_WAIT_IDLE 0x07
45#define DRM_AMDGPU_GEM_VA 0x08
46#define DRM_AMDGPU_WAIT_CS 0x09
47#define DRM_AMDGPU_GEM_OP 0x10
48#define DRM_AMDGPU_GEM_USERPTR 0x11
49
50#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
51#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
52#define DRM_IOCTL_AMDGPU_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CTX, union drm_amdgpu_ctx)
53#define DRM_IOCTL_AMDGPU_BO_LIST DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_BO_LIST, union drm_amdgpu_bo_list)
54#define DRM_IOCTL_AMDGPU_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CS, union drm_amdgpu_cs)
55#define DRM_IOCTL_AMDGPU_INFO DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_INFO, struct drm_amdgpu_info)
56#define DRM_IOCTL_AMDGPU_GEM_METADATA DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_METADATA, struct drm_amdgpu_gem_metadata)
57#define DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_WAIT_IDLE, union drm_amdgpu_gem_wait_idle)
58#define DRM_IOCTL_AMDGPU_GEM_VA DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_VA, struct drm_amdgpu_gem_va)
59#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs)
60#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
61#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
62
63#define AMDGPU_GEM_DOMAIN_CPU 0x1
64#define AMDGPU_GEM_DOMAIN_GTT 0x2
65#define AMDGPU_GEM_DOMAIN_VRAM 0x4
66#define AMDGPU_GEM_DOMAIN_GDS 0x8
67#define AMDGPU_GEM_DOMAIN_GWS 0x10
68#define AMDGPU_GEM_DOMAIN_OA 0x20
69
70/* Flag that CPU access will be required for the case of VRAM domain */
71#define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED (1 << 0)
72/* Flag that CPU access will not work, this VRAM domain is invisible */
73#define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1)
74/* Flag that USWC attributes should be used for GTT */
75#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
76
77struct drm_amdgpu_gem_create_in {
78 /** the requested memory size */
79 uint64_t bo_size;
80 /** physical start_addr alignment in bytes for some HW requirements */
81 uint64_t alignment;
82 /** the requested memory domains */
83 uint64_t domains;
84 /** allocation flags */
85 uint64_t domain_flags;
86};
87
88struct drm_amdgpu_gem_create_out {
89 /** returned GEM object handle */
90 uint32_t handle;
91 uint32_t _pad;
92};
93
94union drm_amdgpu_gem_create {
95 struct drm_amdgpu_gem_create_in in;
96 struct drm_amdgpu_gem_create_out out;
97};
98
99/** Opcode to create new residency list. */
100#define AMDGPU_BO_LIST_OP_CREATE 0
101/** Opcode to destroy previously created residency list */
102#define AMDGPU_BO_LIST_OP_DESTROY 1
103/** Opcode to update resource information in the list */
104#define AMDGPU_BO_LIST_OP_UPDATE 2
105
106struct drm_amdgpu_bo_list_in {
107 /** Type of operation */
108 uint32_t operation;
109 /** Handle of list or 0 if we want to create one */
110 uint32_t list_handle;
111 /** Number of BOs in list */
112 uint32_t bo_number;
113 /** Size of each element describing BO */
114 uint32_t bo_info_size;
115 /** Pointer to array describing BOs */
116 uint64_t bo_info_ptr;
117};
118
119struct drm_amdgpu_bo_list_entry {
120 /** Handle of BO */
121 uint32_t bo_handle;
122 /** New (if specified) BO priority to be used during migration */
123 uint32_t bo_priority;
124};
125
126struct drm_amdgpu_bo_list_out {
127 /** Handle of resource list */
128 uint32_t list_handle;
129 uint32_t _pad;
130};
131
132union drm_amdgpu_bo_list {
133 struct drm_amdgpu_bo_list_in in;
134 struct drm_amdgpu_bo_list_out out;
135};
136
137/* context related */
138#define AMDGPU_CTX_OP_ALLOC_CTX 1
139#define AMDGPU_CTX_OP_FREE_CTX 2
140#define AMDGPU_CTX_OP_QUERY_STATE 3
141
142/* GPU reset status */
143#define AMDGPU_CTX_NO_RESET 0
144/* this the context caused it */
145#define AMDGPU_CTX_GUILTY_RESET 1
146/* some other context caused it */
147#define AMDGPU_CTX_INNOCENT_RESET 2
148/* unknown cause */
149#define AMDGPU_CTX_UNKNOWN_RESET 3
150
151struct drm_amdgpu_ctx_in {
152 /** AMDGPU_CTX_OP_* */
153 uint32_t op;
154 /** For future use, no flags defined so far */
155 uint32_t flags;
156 uint32_t ctx_id;
157 uint32_t _pad;
158};
159
160union drm_amdgpu_ctx_out {
161 struct {
162 uint32_t ctx_id;
163 uint32_t _pad;
164 } alloc;
165
166 struct {
167 /** For future use, no flags defined so far */
168 uint64_t flags;
169 /** Number of resets caused by this context so far. */
170 uint32_t hangs;
171 /** Reset status since the last call of the ioctl. */
172 uint32_t reset_status;
173 } state;
174};
175
176union drm_amdgpu_ctx {
177 struct drm_amdgpu_ctx_in in;
178 union drm_amdgpu_ctx_out out;
179};
180
181/*
182 * This is not a reliable API and you should expect it to fail for any
183 * number of reasons and have fallback path that do not use userptr to
184 * perform any operation.
185 */
186#define AMDGPU_GEM_USERPTR_READONLY (1 << 0)
187#define AMDGPU_GEM_USERPTR_ANONONLY (1 << 1)
188#define AMDGPU_GEM_USERPTR_VALIDATE (1 << 2)
189#define AMDGPU_GEM_USERPTR_REGISTER (1 << 3)
190
191struct drm_amdgpu_gem_userptr {
192 uint64_t addr;
193 uint64_t size;
194 /* AMDGPU_GEM_USERPTR_* */
195 uint32_t flags;
196 /* Resulting GEM handle */
197 uint32_t handle;
198};
199
200/* same meaning as the GB_TILE_MODE and GL_MACRO_TILE_MODE fields */
201#define AMDGPU_TILING_ARRAY_MODE_SHIFT 0
202#define AMDGPU_TILING_ARRAY_MODE_MASK 0xf
203#define AMDGPU_TILING_PIPE_CONFIG_SHIFT 4
204#define AMDGPU_TILING_PIPE_CONFIG_MASK 0x1f
205#define AMDGPU_TILING_TILE_SPLIT_SHIFT 9
206#define AMDGPU_TILING_TILE_SPLIT_MASK 0x7
207#define AMDGPU_TILING_MICRO_TILE_MODE_SHIFT 12
208#define AMDGPU_TILING_MICRO_TILE_MODE_MASK 0x7
209#define AMDGPU_TILING_BANK_WIDTH_SHIFT 15
210#define AMDGPU_TILING_BANK_WIDTH_MASK 0x3
211#define AMDGPU_TILING_BANK_HEIGHT_SHIFT 17
212#define AMDGPU_TILING_BANK_HEIGHT_MASK 0x3
213#define AMDGPU_TILING_MACRO_TILE_ASPECT_SHIFT 19
214#define AMDGPU_TILING_MACRO_TILE_ASPECT_MASK 0x3
215#define AMDGPU_TILING_NUM_BANKS_SHIFT 21
216#define AMDGPU_TILING_NUM_BANKS_MASK 0x3
217
218#define AMDGPU_TILING_SET(field, value) \
219 (((value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT)
220#define AMDGPU_TILING_GET(value, field) \
221 (((value) >> AMDGPU_TILING_##field##_SHIFT) & AMDGPU_TILING_##field##_MASK)
222
223#define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
224#define AMDGPU_GEM_METADATA_OP_GET_METADATA 2
225
226/** The same structure is shared for input/output */
227struct drm_amdgpu_gem_metadata {
228 /** GEM Object handle */
229 uint32_t handle;
230 /** Do we want get or set metadata */
231 uint32_t op;
232 struct {
233 /** For future use, no flags defined so far */
234 uint64_t flags;
235 /** family specific tiling info */
236 uint64_t tiling_info;
237 uint32_t data_size_bytes;
238 uint32_t data[64];
239 } data;
240};
241
242struct drm_amdgpu_gem_mmap_in {
243 /** the GEM object handle */
244 uint32_t handle;
245 uint32_t _pad;
246};
247
248struct drm_amdgpu_gem_mmap_out {
249 /** mmap offset from the vma offset manager */
250 uint64_t addr_ptr;
251};
252
253union drm_amdgpu_gem_mmap {
254 struct drm_amdgpu_gem_mmap_in in;
255 struct drm_amdgpu_gem_mmap_out out;
256};
257
258struct drm_amdgpu_gem_wait_idle_in {
259 /** GEM object handle */
260 uint32_t handle;
261 /** For future use, no flags defined so far */
262 uint32_t flags;
263 /** Absolute timeout to wait */
264 uint64_t timeout;
265};
266
267struct drm_amdgpu_gem_wait_idle_out {
268 /** BO status: 0 - BO is idle, 1 - BO is busy */
269 uint32_t status;
270 /** Returned current memory domain */
271 uint32_t domain;
272};
273
274union drm_amdgpu_gem_wait_idle {
275 struct drm_amdgpu_gem_wait_idle_in in;
276 struct drm_amdgpu_gem_wait_idle_out out;
277};
278
279struct drm_amdgpu_wait_cs_in {
280 /** Command submission handle */
281 uint64_t handle;
282 /** Absolute timeout to wait */
283 uint64_t timeout;
284 uint32_t ip_type;
285 uint32_t ip_instance;
286 uint32_t ring;
287 uint32_t ctx_id;
288};
289
290struct drm_amdgpu_wait_cs_out {
291 /** CS status: 0 - CS completed, 1 - CS still busy */
292 uint64_t status;
293};
294
295union drm_amdgpu_wait_cs {
296 struct drm_amdgpu_wait_cs_in in;
297 struct drm_amdgpu_wait_cs_out out;
298};
299
300#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0
301#define AMDGPU_GEM_OP_SET_PLACEMENT 1
302
303/* Sets or returns a value associated with a buffer. */
304struct drm_amdgpu_gem_op {
305 /** GEM object handle */
306 uint32_t handle;
307 /** AMDGPU_GEM_OP_* */
308 uint32_t op;
309 /** Input or return value */
310 uint64_t value;
311};
312
313#define AMDGPU_VA_OP_MAP 1
314#define AMDGPU_VA_OP_UNMAP 2
315
316/* Delay the page table update till the next CS */
317#define AMDGPU_VM_DELAY_UPDATE (1 << 0)
318
319/* Mapping flags */
320/* readable mapping */
321#define AMDGPU_VM_PAGE_READABLE (1 << 1)
322/* writable mapping */
323#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2)
324/* executable mapping, new for VI */
325#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3)
326
327struct drm_amdgpu_gem_va {
328 /** GEM object handle */
329 uint32_t handle;
330 uint32_t _pad;
331 /** AMDGPU_VA_OP_* */
332 uint32_t operation;
333 /** AMDGPU_VM_PAGE_* */
334 uint32_t flags;
335 /** va address to assign . Must be correctly aligned.*/
336 uint64_t va_address;
337 /** Specify offset inside of BO to assign. Must be correctly aligned.*/
338 uint64_t offset_in_bo;
339 /** Specify mapping size. Must be correctly aligned. */
340 uint64_t map_size;
341};
342
343#define AMDGPU_HW_IP_GFX 0
344#define AMDGPU_HW_IP_COMPUTE 1
345#define AMDGPU_HW_IP_DMA 2
346#define AMDGPU_HW_IP_UVD 3
347#define AMDGPU_HW_IP_VCE 4
348#define AMDGPU_HW_IP_NUM 5
349
350#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
351
352#define AMDGPU_CHUNK_ID_IB 0x01
353#define AMDGPU_CHUNK_ID_FENCE 0x02
354#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
355
356struct drm_amdgpu_cs_chunk {
357 uint32_t chunk_id;
358 uint32_t length_dw;
359 uint64_t chunk_data;
360};
361
362struct drm_amdgpu_cs_in {
363 /** Rendering context id */
364 uint32_t ctx_id;
365 /** Handle of resource list associated with CS */
366 uint32_t bo_list_handle;
367 uint32_t num_chunks;
368 uint32_t _pad;
369 /** this points to uint64_t * which point to cs chunks */
370 uint64_t chunks;
371};
372
373struct drm_amdgpu_cs_out {
374 uint64_t handle;
375};
376
377union drm_amdgpu_cs {
378 struct drm_amdgpu_cs_in in;
379 struct drm_amdgpu_cs_out out;
380};
381
382/* Specify flags to be used for IB */
383
384/* This IB should be submitted to CE */
385#define AMDGPU_IB_FLAG_CE (1<<0)
386
387/* CE Preamble */
388#define AMDGPU_IB_FLAG_PREAMBLE (1<<1)
389
390struct drm_amdgpu_cs_chunk_ib {
391 uint32_t _pad;
392 /** AMDGPU_IB_FLAG_* */
393 uint32_t flags;
394 /** Virtual address to begin IB execution */
395 uint64_t va_start;
396 /** Size of submission */
397 uint32_t ib_bytes;
398 /** HW IP to submit to */
399 uint32_t ip_type;
400 /** HW IP index of the same type to submit to */
401 uint32_t ip_instance;
402 /** Ring index to submit to */
403 uint32_t ring;
404};
405
406struct drm_amdgpu_cs_chunk_dep {
407 uint32_t ip_type;
408 uint32_t ip_instance;
409 uint32_t ring;
410 uint32_t ctx_id;
411 uint64_t handle;
412};
413
414struct drm_amdgpu_cs_chunk_fence {
415 uint32_t handle;
416 uint32_t offset;
417};
418
419struct drm_amdgpu_cs_chunk_data {
420 union {
421 struct drm_amdgpu_cs_chunk_ib ib_data;
422 struct drm_amdgpu_cs_chunk_fence fence_data;
423 };
424};
425
426/**
427 * Query h/w info: Flag that this is integrated (a.h.a. fusion) GPU
428 *
429 */
430#define AMDGPU_IDS_FLAGS_FUSION 0x1
431
432/* indicate if acceleration can be working */
433#define AMDGPU_INFO_ACCEL_WORKING 0x00
434/* get the crtc_id from the mode object id? */
435#define AMDGPU_INFO_CRTC_FROM_ID 0x01
436/* query hw IP info */
437#define AMDGPU_INFO_HW_IP_INFO 0x02
438/* query hw IP instance count for the specified type */
439#define AMDGPU_INFO_HW_IP_COUNT 0x03
440/* timestamp for GL_ARB_timer_query */
441#define AMDGPU_INFO_TIMESTAMP 0x05
442/* Query the firmware version */
443#define AMDGPU_INFO_FW_VERSION 0x0e
444 /* Subquery id: Query VCE firmware version */
445 #define AMDGPU_INFO_FW_VCE 0x1
446 /* Subquery id: Query UVD firmware version */
447 #define AMDGPU_INFO_FW_UVD 0x2
448 /* Subquery id: Query GMC firmware version */
449 #define AMDGPU_INFO_FW_GMC 0x03
450 /* Subquery id: Query GFX ME firmware version */
451 #define AMDGPU_INFO_FW_GFX_ME 0x04
452 /* Subquery id: Query GFX PFP firmware version */
453 #define AMDGPU_INFO_FW_GFX_PFP 0x05
454 /* Subquery id: Query GFX CE firmware version */
455 #define AMDGPU_INFO_FW_GFX_CE 0x06
456 /* Subquery id: Query GFX RLC firmware version */
457 #define AMDGPU_INFO_FW_GFX_RLC 0x07
458 /* Subquery id: Query GFX MEC firmware version */
459 #define AMDGPU_INFO_FW_GFX_MEC 0x08
460 /* Subquery id: Query SMC firmware version */
461 #define AMDGPU_INFO_FW_SMC 0x0a
462 /* Subquery id: Query SDMA firmware version */
463 #define AMDGPU_INFO_FW_SDMA 0x0b
464/* number of bytes moved for TTM migration */
465#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
466/* the used VRAM size */
467#define AMDGPU_INFO_VRAM_USAGE 0x10
468/* the used GTT size */
469#define AMDGPU_INFO_GTT_USAGE 0x11
470/* Information about GDS, etc. resource configuration */
471#define AMDGPU_INFO_GDS_CONFIG 0x13
472/* Query information about VRAM and GTT domains */
473#define AMDGPU_INFO_VRAM_GTT 0x14
474/* Query information about register in MMR address space*/
475#define AMDGPU_INFO_READ_MMR_REG 0x15
476/* Query information about device: rev id, family, etc. */
477#define AMDGPU_INFO_DEV_INFO 0x16
478/* visible vram usage */
479#define AMDGPU_INFO_VIS_VRAM_USAGE 0x17
480
481#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
482#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
483#define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
484#define AMDGPU_INFO_MMR_SH_INDEX_MASK 0xff
485
486/* Input structure for the INFO ioctl */
487struct drm_amdgpu_info {
488 /* Where the return value will be stored */
489 uint64_t return_pointer;
490 /* The size of the return value. Just like "size" in "snprintf",
491 * it limits how many bytes the kernel can write. */
492 uint32_t return_size;
493 /* The query request id. */
494 uint32_t query;
495
496 union {
497 struct {
498 uint32_t id;
499 uint32_t _pad;
500 } mode_crtc;
501
502 struct {
503 /** AMDGPU_HW_IP_* */
504 uint32_t type;
505 /**
506 * Index of the IP if there are more IPs of the same
507 * type. Ignored by AMDGPU_INFO_HW_IP_COUNT.
508 */
509 uint32_t ip_instance;
510 } query_hw_ip;
511
512 struct {
513 uint32_t dword_offset;
514 /** number of registers to read */
515 uint32_t count;
516 uint32_t instance;
517 /** For future use, no flags defined so far */
518 uint32_t flags;
519 } read_mmr_reg;
520
521 struct {
522 /** AMDGPU_INFO_FW_* */
523 uint32_t fw_type;
524 /**
525 * Index of the IP if there are more IPs of
526 * the same type.
527 */
528 uint32_t ip_instance;
529 /**
530 * Index of the engine. Whether this is used depends
531 * on the firmware type. (e.g. MEC, SDMA)
532 */
533 uint32_t index;
534 uint32_t _pad;
535 } query_fw;
536 };
537};
538
539struct drm_amdgpu_info_gds {
540 /** GDS GFX partition size */
541 uint32_t gds_gfx_partition_size;
542 /** GDS compute partition size */
543 uint32_t compute_partition_size;
544 /** total GDS memory size */
545 uint32_t gds_total_size;
546 /** GWS size per GFX partition */
547 uint32_t gws_per_gfx_partition;
548 /** GSW size per compute partition */
549 uint32_t gws_per_compute_partition;
550 /** OA size per GFX partition */
551 uint32_t oa_per_gfx_partition;
552 /** OA size per compute partition */
553 uint32_t oa_per_compute_partition;
554 uint32_t _pad;
555};
556
557struct drm_amdgpu_info_vram_gtt {
558 uint64_t vram_size;
559 uint64_t vram_cpu_accessible_size;
560 uint64_t gtt_size;
561};
562
563struct drm_amdgpu_info_firmware {
564 uint32_t ver;
565 uint32_t feature;
566};
567
568#define AMDGPU_VRAM_TYPE_UNKNOWN 0
569#define AMDGPU_VRAM_TYPE_GDDR1 1
570#define AMDGPU_VRAM_TYPE_DDR2 2
571#define AMDGPU_VRAM_TYPE_GDDR3 3
572#define AMDGPU_VRAM_TYPE_GDDR4 4
573#define AMDGPU_VRAM_TYPE_GDDR5 5
574#define AMDGPU_VRAM_TYPE_HBM 6
575#define AMDGPU_VRAM_TYPE_DDR3 7
576
577struct drm_amdgpu_info_device {
578 /** PCI Device ID */
579 uint32_t device_id;
580 /** Internal chip revision: A0, A1, etc.) */
581 uint32_t chip_rev;
582 uint32_t external_rev;
583 /** Revision id in PCI Config space */
584 uint32_t pci_rev;
585 uint32_t family;
586 uint32_t num_shader_engines;
587 uint32_t num_shader_arrays_per_engine;
588 /* in KHz */
589 uint32_t gpu_counter_freq;
590 uint64_t max_engine_clock;
591 uint64_t max_memory_clock;
592 /* cu information */
593 uint32_t cu_active_number;
594 uint32_t cu_ao_mask;
595 uint32_t cu_bitmap[4][4];
596 /** Render backend pipe mask. One render backend is CB+DB. */
597 uint32_t enabled_rb_pipes_mask;
598 uint32_t num_rb_pipes;
599 uint32_t num_hw_gfx_contexts;
600 uint32_t _pad;
601 uint64_t ids_flags;
602 /** Starting virtual address for UMDs. */
603 uint64_t virtual_address_offset;
604 /** The maximum virtual address */
605 uint64_t virtual_address_max;
606 /** Required alignment of virtual addresses. */
607 uint32_t virtual_address_alignment;
608 /** Page table entry - fragment size */
609 uint32_t pte_fragment_size;
610 uint32_t gart_page_size;
611 /** constant engine ram size*/
612 uint32_t ce_ram_size;
613 /** video memory type info*/
614 uint32_t vram_type;
615 /** video memory bit width*/
616 uint32_t vram_bit_width;
617 /* vce harvesting instance */
618 uint32_t vce_harvest_config;
619};
620
621struct drm_amdgpu_info_hw_ip {
622 /** Version of h/w IP */
623 uint32_t hw_ip_version_major;
624 uint32_t hw_ip_version_minor;
625 /** Capabilities */
626 uint64_t capabilities_flags;
627 /** command buffer address start alignment*/
628 uint32_t ib_start_alignment;
629 /** command buffer size alignment*/
630 uint32_t ib_size_alignment;
631 /** Bitmask of available rings. Bit 0 means ring 0, etc. */
632 uint32_t available_rings;
633 uint32_t _pad;
634};
635
636/*
637 * Supported GPU families
638 */
639#define AMDGPU_FAMILY_UNKNOWN 0
640#define AMDGPU_FAMILY_CI 120 /* Bonaire, Hawaii */
641#define AMDGPU_FAMILY_KV 125 /* Kaveri, Kabini, Mullins */
642#define AMDGPU_FAMILY_VI 130 /* Iceland, Tonga */
643#define AMDGPU_FAMILY_CZ 135 /* Carrizo */
644
645#endif
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 795c89e5..d36331a8 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -642,6 +642,13 @@ struct drm_get_cap {
642 */ 642 */
643#define DRM_CLIENT_CAP_ATOMIC 3 643#define DRM_CLIENT_CAP_ATOMIC 3
644 644
645/**
646 * DRM_CLIENT_CAP_ATOMIC
647 *
648 * If set to 1, the DRM core will allow atomic modesetting requests.
649 */
650#define DRM_CLIENT_CAP_ATOMIC 3
651
645/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ 652/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
646struct drm_set_client_cap { 653struct drm_set_client_cap {
647 __u64 capability; 654 __u64 capability;
@@ -816,6 +823,7 @@ struct drm_event_vblank {
816#define DRM_CAP_PRIME 0x5 823#define DRM_CAP_PRIME 0x5
817#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 824#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
818#define DRM_CAP_ASYNC_PAGE_FLIP 0x7 825#define DRM_CAP_ASYNC_PAGE_FLIP 0x7
826#define DRM_CAP_ADDFB2_MODIFIERS 0x10
819 827
820#define DRM_PRIME_CAP_IMPORT 0x1 828#define DRM_PRIME_CAP_IMPORT 0x1
821#define DRM_PRIME_CAP_EXPORT 0x2 829#define DRM_PRIME_CAP_EXPORT 0x2
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 85facb0a..e741b09a 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -127,4 +127,97 @@
127#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ 127#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
128#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ 128#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
129 129
130
131/*
132 * Format Modifiers:
133 *
134 * Format modifiers describe, typically, a re-ordering or modification
135 * of the data in a plane of an FB. This can be used to express tiled/
136 * swizzled formats, or compression, or a combination of the two.
137 *
138 * The upper 8 bits of the format modifier are a vendor-id as assigned
139 * below. The lower 56 bits are assigned as vendor sees fit.
140 */
141
142/* Vendor Ids: */
143#define DRM_FORMAT_MOD_NONE 0
144#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01
145#define DRM_FORMAT_MOD_VENDOR_AMD 0x02
146#define DRM_FORMAT_MOD_VENDOR_NV 0x03
147#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
148#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
149/* add more to the end as needed */
150
151#define fourcc_mod_code(vendor, val) \
152 ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
153
154/*
155 * Format Modifier tokens:
156 *
157 * When adding a new token please document the layout with a code comment,
158 * similar to the fourcc codes above. drm_fourcc.h is considered the
159 * authoritative source for all of these.
160 */
161
162/* Intel framebuffer modifiers */
163
164/*
165 * Intel X-tiling layout
166 *
167 * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb)
168 * in row-major layout. Within the tile bytes are laid out row-major, with
169 * a platform-dependent stride. On top of that the memory can apply
170 * platform-depending swizzling of some higher address bits into bit6.
171 *
172 * This format is highly platforms specific and not useful for cross-driver
173 * sharing. It exists since on a given platform it does uniquely identify the
174 * layout in a simple way for i915-specific userspace.
175 */
176#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1)
177
178/*
179 * Intel Y-tiling layout
180 *
181 * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb)
182 * in row-major layout. Within the tile bytes are laid out in OWORD (16 bytes)
183 * chunks column-major, with a platform-dependent height. On top of that the
184 * memory can apply platform-depending swizzling of some higher address bits
185 * into bit6.
186 *
187 * This format is highly platforms specific and not useful for cross-driver
188 * sharing. It exists since on a given platform it does uniquely identify the
189 * layout in a simple way for i915-specific userspace.
190 */
191#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2)
192
193/*
194 * Intel Yf-tiling layout
195 *
196 * This is a tiled layout using 4Kb tiles in row-major layout.
197 * Within the tile pixels are laid out in 16 256 byte units / sub-tiles which
198 * are arranged in four groups (two wide, two high) with column-major layout.
199 * Each group therefore consits out of four 256 byte units, which are also laid
200 * out as 2x2 column-major.
201 * 256 byte units are made out of four 64 byte blocks of pixels, producing
202 * either a square block or a 2:1 unit.
203 * 64 byte blocks of pixels contain four pixel rows of 16 bytes, where the width
204 * in pixel depends on the pixel depth.
205 */
206#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
207
208/*
209 * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
210 *
211 * Macroblocks are laid in a Z-shape, and each pixel data is following the
212 * standard NV12 style.
213 * As for NV12, an image is the result of two frame buffers: one for Y,
214 * one for the interleaved Cb/Cr components (1/2 the height of the Y buffer).
215 * Alignment requirements are (for each buffer):
216 * - multiple of 128 pixels for the width
217 * - multiple of 32 pixels for the height
218 *
219 * For more information: see http://linuxtv.org/downloads/v4l-dvb-apis/re32.html
220 */
221#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
222
130#endif /* DRM_FOURCC_H */ 223#endif /* DRM_FOURCC_H */
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 09b41d85..59e67b14 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -337,7 +337,8 @@ struct drm_mode_fb_cmd {
337 __u32 handle; 337 __u32 handle;
338}; 338};
339 339
340#define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */ 340#define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */
341#define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifer[] */
341 342
342struct drm_mode_fb_cmd2 { 343struct drm_mode_fb_cmd2 {
343 __u32 fb_id; 344 __u32 fb_id;
@@ -358,10 +359,18 @@ struct drm_mode_fb_cmd2 {
358 * So it would consist of Y as offset[0] and UV as 359 * So it would consist of Y as offset[0] and UV as
359 * offset[1]. Note that offset[0] will generally 360 * offset[1]. Note that offset[0] will generally
360 * be 0. 361 * be 0.
362 *
363 * To accommodate tiled, compressed, etc formats, a per-plane
364 * modifier can be specified. The default value of zero
365 * indicates "native" format as specified by the fourcc.
366 * Vendor specific modifier token. This allows, for example,
367 * different tiling/swizzling pattern on different planes.
368 * See discussion above of DRM_FORMAT_MOD_xxx.
361 */ 369 */
362 __u32 handles[4]; 370 __u32 handles[4];
363 __u32 pitches[4]; /* pitch for each plane */ 371 __u32 pitches[4]; /* pitch for each plane */
364 __u32 offsets[4]; /* offset of each plane */ 372 __u32 offsets[4]; /* offset of each plane */
373 __u64 modifier[4]; /* ie, tiling, compressed (per plane) */
365}; 374};
366 375
367#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01 376#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
@@ -523,9 +532,9 @@ struct drm_mode_destroy_dumb {
523}; 532};
524 533
525/* page-flip flags are valid, plus: */ 534/* page-flip flags are valid, plus: */
526#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100 535#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
527#define DRM_MODE_ATOMIC_NONBLOCK 0x0200 536#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
528#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400 537#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
529 538
530#define DRM_MODE_ATOMIC_FLAGS (\ 539#define DRM_MODE_ATOMIC_FLAGS (\
531 DRM_MODE_PAGE_FLIP_EVENT |\ 540 DRM_MODE_PAGE_FLIP_EVENT |\
@@ -565,4 +574,5 @@ struct drm_mode_destroy_blob {
565 __u32 blob_id; 574 __u32 blob_id;
566}; 575};
567 576
577
568#endif 578#endif
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 15dd01d4..0e51d421 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -27,7 +27,7 @@
27#ifndef _I915_DRM_H_ 27#ifndef _I915_DRM_H_
28#define _I915_DRM_H_ 28#define _I915_DRM_H_
29 29
30#include <drm.h> 30#include "drm.h"
31 31
32/* Please note that modifications to all structs defined here are 32/* Please note that modifications to all structs defined here are
33 * subject to backwards-compatibility constraints. 33 * subject to backwards-compatibility constraints.
@@ -171,8 +171,12 @@ typedef struct _drm_i915_sarea {
171#define I915_BOX_TEXTURE_LOAD 0x8 171#define I915_BOX_TEXTURE_LOAD 0x8
172#define I915_BOX_LOST_CONTEXT 0x10 172#define I915_BOX_LOST_CONTEXT 0x10
173 173
174/* I915 specific ioctls 174/*
175 * The device specific ioctl range is 0x40 to 0x79. 175 * i915 specific ioctls.
176 *
177 * The device specific ioctl range is [DRM_COMMAND_BASE, DRM_COMMAND_END) ie
178 * [0x40, 0xa0) (a0 is excluded). The numbers below are defined as offset
179 * against DRM_COMMAND_BASE and should be between [0x0, 0x60).
176 */ 180 */
177#define DRM_I915_INIT 0x00 181#define DRM_I915_INIT 0x00
178#define DRM_I915_FLUSH 0x01 182#define DRM_I915_FLUSH 0x01
@@ -224,6 +228,8 @@ typedef struct _drm_i915_sarea {
224#define DRM_I915_REG_READ 0x31 228#define DRM_I915_REG_READ 0x31
225#define DRM_I915_GET_RESET_STATS 0x32 229#define DRM_I915_GET_RESET_STATS 0x32
226#define DRM_I915_GEM_USERPTR 0x33 230#define DRM_I915_GEM_USERPTR 0x33
231#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
232#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
227 233
228#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) 234#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
229#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) 235#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -268,13 +274,15 @@ typedef struct _drm_i915_sarea {
268#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image) 274#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
269#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) 275#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
270#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) 276#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
271#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) 277#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
272#define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait) 278#define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
273#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create) 279#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
274#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy) 280#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
275#define DRM_IOCTL_I915_REG_READ DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read) 281#define DRM_IOCTL_I915_REG_READ DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
276#define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats) 282#define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats)
277#define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr) 283#define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr)
284#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
285#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
278 286
279/* Allow drivers to submit batchbuffers directly to hardware, relying 287/* Allow drivers to submit batchbuffers directly to hardware, relying
280 * on the security mechanisms provided by hardware. 288 * on the security mechanisms provided by hardware.
@@ -340,9 +348,22 @@ typedef struct drm_i915_irq_wait {
340#define I915_PARAM_HAS_EXEC_HANDLE_LUT 26 348#define I915_PARAM_HAS_EXEC_HANDLE_LUT 26
341#define I915_PARAM_HAS_WT 27 349#define I915_PARAM_HAS_WT 27
342#define I915_PARAM_CMD_PARSER_VERSION 28 350#define I915_PARAM_CMD_PARSER_VERSION 28
351#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29
352#define I915_PARAM_MMAP_VERSION 30
353#define I915_PARAM_HAS_BSD2 31
354#define I915_PARAM_REVISION 32
355#define I915_PARAM_SUBSLICE_TOTAL 33
356#define I915_PARAM_EU_TOTAL 34
357#define I915_PARAM_HAS_GPU_RESET 35
358#define I915_PARAM_HAS_RESOURCE_STREAMER 36
359#define I915_PARAM_HAS_EXEC_SOFTPIN 37
343 360
344typedef struct drm_i915_getparam { 361typedef struct drm_i915_getparam {
345 int param; 362 __s32 param;
363 /*
364 * WARNING: Using pointers instead of fixed-size u64 means we need to write
365 * compat32 code. Don't repeat this mistake.
366 */
346 int *value; 367 int *value;
347} drm_i915_getparam_t; 368} drm_i915_getparam_t;
348 369
@@ -487,6 +508,14 @@ struct drm_i915_gem_mmap {
487 * This is a fixed-size type for 32/64 compatibility. 508 * This is a fixed-size type for 32/64 compatibility.
488 */ 509 */
489 __u64 addr_ptr; 510 __u64 addr_ptr;
511
512 /**
513 * Flags for extended behaviour.
514 *
515 * Added in version 2.
516 */
517 __u64 flags;
518#define I915_MMAP_WC 0x1
490}; 519};
491 520
492struct drm_i915_gem_mmap_gtt { 521struct drm_i915_gem_mmap_gtt {
@@ -654,15 +683,21 @@ struct drm_i915_gem_exec_object2 {
654 __u64 alignment; 683 __u64 alignment;
655 684
656 /** 685 /**
657 * Returned value of the updated offset of the object, for future 686 * When the EXEC_OBJECT_PINNED flag is specified this is populated by
658 * presumed_offset writes. 687 * the user with the GTT offset at which this object will be pinned.
688 * When the I915_EXEC_NO_RELOC flag is specified this must contain the
689 * presumed_offset of the object.
690 * During execbuffer2 the kernel populates it with the value of the
691 * current GTT offset of the object, for future presumed_offset writes.
659 */ 692 */
660 __u64 offset; 693 __u64 offset;
661 694
662#define EXEC_OBJECT_NEEDS_FENCE (1<<0) 695#define EXEC_OBJECT_NEEDS_FENCE (1<<0)
663#define EXEC_OBJECT_NEEDS_GTT (1<<1) 696#define EXEC_OBJECT_NEEDS_GTT (1<<1)
664#define EXEC_OBJECT_WRITE (1<<2) 697#define EXEC_OBJECT_WRITE (1<<2)
665#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_WRITE<<1) 698#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
699#define EXEC_OBJECT_PINNED (1<<4)
700#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)
666 __u64 flags; 701 __u64 flags;
667 702
668 __u64 rsvd1; 703 __u64 rsvd1;
@@ -736,7 +771,18 @@ struct drm_i915_gem_execbuffer2 {
736 */ 771 */
737#define I915_EXEC_HANDLE_LUT (1<<12) 772#define I915_EXEC_HANDLE_LUT (1<<12)
738 773
739#define __I915_EXEC_UNKNOWN_FLAGS -(I915_EXEC_HANDLE_LUT<<1) 774/** Used for switching BSD rings on the platforms with two BSD rings */
775#define I915_EXEC_BSD_MASK (3<<13)
776#define I915_EXEC_BSD_DEFAULT (0<<13) /* default ping-pong mode */
777#define I915_EXEC_BSD_RING1 (1<<13)
778#define I915_EXEC_BSD_RING2 (2<<13)
779
780/** Tell the kernel that the batchbuffer is processed by
781 * the resource streamer.
782 */
783#define I915_EXEC_RESOURCE_STREAMER (1<<15)
784
785#define __I915_EXEC_UNKNOWN_FLAGS -(I915_EXEC_RESOURCE_STREAMER<<1)
740 786
741#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) 787#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
742#define i915_execbuffer2_set_context_id(eb2, context) \ 788#define i915_execbuffer2_set_context_id(eb2, context) \
@@ -876,6 +922,12 @@ struct drm_i915_gem_get_tiling {
876 * mmap mapping. 922 * mmap mapping.
877 */ 923 */
878 __u32 swizzle_mode; 924 __u32 swizzle_mode;
925
926 /**
927 * Returned address bit 6 swizzling required for CPU access through
928 * mmap mapping whilst bound.
929 */
930 __u32 phys_swizzle_mode;
879}; 931};
880 932
881struct drm_i915_gem_get_aperture { 933struct drm_i915_gem_get_aperture {
@@ -966,6 +1018,7 @@ struct drm_intel_overlay_put_image {
966/* flags */ 1018/* flags */
967#define I915_OVERLAY_UPDATE_ATTRS (1<<0) 1019#define I915_OVERLAY_UPDATE_ATTRS (1<<0)
968#define I915_OVERLAY_UPDATE_GAMMA (1<<1) 1020#define I915_OVERLAY_UPDATE_GAMMA (1<<1)
1021#define I915_OVERLAY_DISABLE_DEST_COLORKEY (1<<2)
969struct drm_intel_overlay_attrs { 1022struct drm_intel_overlay_attrs {
970 __u32 flags; 1023 __u32 flags;
971 __u32 color_key; 1024 __u32 color_key;
@@ -1032,9 +1085,23 @@ struct drm_i915_gem_context_destroy {
1032}; 1085};
1033 1086
1034struct drm_i915_reg_read { 1087struct drm_i915_reg_read {
1088 /*
1089 * Register offset.
1090 * For 64bit wide registers where the upper 32bits don't immediately
1091 * follow the lower 32bits, the offset of the lower 32bits must
1092 * be specified
1093 */
1035 __u64 offset; 1094 __u64 offset;
1036 __u64 val; /* Return value */ 1095 __u64 val; /* Return value */
1037}; 1096};
1097/* Known registers:
1098 *
1099 * Render engine timestamp - 0x2358 + 64bit - gen7+
1100 * - Note this register returns an invalid value if using the default
1101 * single instruction 8byte read, in order to workaround that use
1102 * offset (0x2538 | 1) instead.
1103 *
1104 */
1038 1105
1039struct drm_i915_reset_stats { 1106struct drm_i915_reset_stats {
1040 __u32 ctx_id; 1107 __u32 ctx_id;
@@ -1059,11 +1126,21 @@ struct drm_i915_gem_userptr {
1059#define I915_USERPTR_READ_ONLY 0x1 1126#define I915_USERPTR_READ_ONLY 0x1
1060#define I915_USERPTR_UNSYNCHRONIZED 0x80000000 1127#define I915_USERPTR_UNSYNCHRONIZED 0x80000000
1061 /** 1128 /**
1062 * Returned handle for the object. 1129 * Returned handle for the object.
1063 * 1130 *
1064 * Object handles are nonzero. 1131 * Object handles are nonzero.
1065 */ 1132 */
1066 __u32 handle; 1133 __u32 handle;
1067}; 1134};
1068 1135
1136struct drm_i915_gem_context_param {
1137 __u32 ctx_id;
1138 __u32 size;
1139 __u64 param;
1140#define I915_CONTEXT_PARAM_BAN_PERIOD 0x1
1141#define I915_CONTEXT_PARAM_NO_ZEROMAP 0x2
1142#define I915_CONTEXT_PARAM_GTT_SIZE 0x3
1143 __u64 value;
1144};
1145
1069#endif /* _I915_DRM_H_ */ 1146#endif /* _I915_DRM_H_ */
diff --git a/include/drm/virtgpu_drm.h b/include/drm/virtgpu_drm.h
new file mode 100644
index 00000000..abf11c58
--- /dev/null
+++ b/include/drm/virtgpu_drm.h
@@ -0,0 +1,167 @@
1/*
2 * Copyright 2013 Red Hat
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24#ifndef VIRTGPU_DRM_H
25#define VIRTGPU_DRM_H
26
27#include <stddef.h>
28#include "drm/drm.h"
29
30/* Please note that modifications to all structs defined here are
31 * subject to backwards-compatibility constraints.
32 *
33 * Do not use pointers, use uint64_t instead for 32 bit / 64 bit user/kernel
34 * compatibility Keep fields aligned to their size
35 */
36
37#define DRM_VIRTGPU_MAP 0x01
38#define DRM_VIRTGPU_EXECBUFFER 0x02
39#define DRM_VIRTGPU_GETPARAM 0x03
40#define DRM_VIRTGPU_RESOURCE_CREATE 0x04
41#define DRM_VIRTGPU_RESOURCE_INFO 0x05
42#define DRM_VIRTGPU_TRANSFER_FROM_HOST 0x06
43#define DRM_VIRTGPU_TRANSFER_TO_HOST 0x07
44#define DRM_VIRTGPU_WAIT 0x08
45#define DRM_VIRTGPU_GET_CAPS 0x09
46
47struct drm_virtgpu_map {
48 uint64_t offset; /* use for mmap system call */
49 uint32_t handle;
50 uint32_t pad;
51};
52
53struct drm_virtgpu_execbuffer {
54 uint32_t flags; /* for future use */
55 uint32_t size;
56 uint64_t command; /* void* */
57 uint64_t bo_handles;
58 uint32_t num_bo_handles;
59 uint32_t pad;
60};
61
62#define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */
63
64struct drm_virtgpu_getparam {
65 uint64_t param;
66 uint64_t value;
67};
68
69/* NO_BO flags? NO resource flag? */
70/* resource flag for y_0_top */
71struct drm_virtgpu_resource_create {
72 uint32_t target;
73 uint32_t format;
74 uint32_t bind;
75 uint32_t width;
76 uint32_t height;
77 uint32_t depth;
78 uint32_t array_size;
79 uint32_t last_level;
80 uint32_t nr_samples;
81 uint32_t flags;
82 uint32_t bo_handle; /* if this is set - recreate a new resource attached to this bo ? */
83 uint32_t res_handle; /* returned by kernel */
84 uint32_t size; /* validate transfer in the host */
85 uint32_t stride; /* validate transfer in the host */
86};
87
88struct drm_virtgpu_resource_info {
89 uint32_t bo_handle;
90 uint32_t res_handle;
91 uint32_t size;
92 uint32_t stride;
93};
94
95struct drm_virtgpu_3d_box {
96 uint32_t x;
97 uint32_t y;
98 uint32_t z;
99 uint32_t w;
100 uint32_t h;
101 uint32_t d;
102};
103
104struct drm_virtgpu_3d_transfer_to_host {
105 uint32_t bo_handle;
106 struct drm_virtgpu_3d_box box;
107 uint32_t level;
108 uint32_t offset;
109};
110
111struct drm_virtgpu_3d_transfer_from_host {
112 uint32_t bo_handle;
113 struct drm_virtgpu_3d_box box;
114 uint32_t level;
115 uint32_t offset;
116};
117
118#define VIRTGPU_WAIT_NOWAIT 1 /* like it */
119struct drm_virtgpu_3d_wait {
120 uint32_t handle; /* 0 is an invalid handle */
121 uint32_t flags;
122};
123
124struct drm_virtgpu_get_caps {
125 uint32_t cap_set_id;
126 uint32_t cap_set_ver;
127 uint64_t addr;
128 uint32_t size;
129 uint32_t pad;
130};
131
132#define DRM_IOCTL_VIRTGPU_MAP \
133 DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)
134
135#define DRM_IOCTL_VIRTGPU_EXECBUFFER \
136 DRM_IOW(DRM_COMMAND_BASE + DRM_VIRTGPU_EXECBUFFER,\
137 struct drm_virtgpu_execbuffer)
138
139#define DRM_IOCTL_VIRTGPU_GETPARAM \
140 DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GETPARAM,\
141 struct drm_virtgpu_getparam)
142
143#define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE \
144 DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE, \
145 struct drm_virtgpu_resource_create)
146
147#define DRM_IOCTL_VIRTGPU_RESOURCE_INFO \
148 DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_INFO, \
149 struct drm_virtgpu_resource_info)
150
151#define DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST \
152 DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_TRANSFER_FROM_HOST, \
153 struct drm_virtgpu_3d_transfer_from_host)
154
155#define DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST \
156 DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_TRANSFER_TO_HOST, \
157 struct drm_virtgpu_3d_transfer_to_host)
158
159#define DRM_IOCTL_VIRTGPU_WAIT \
160 DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_WAIT, \
161 struct drm_virtgpu_3d_wait)
162
163#define DRM_IOCTL_VIRTGPU_GET_CAPS \
164 DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GET_CAPS, \
165 struct drm_virtgpu_get_caps)
166
167#endif
diff --git a/intel/Android.mk b/intel/Android.mk
index bb474620..791f9627 100644
--- a/intel/Android.mk
+++ b/intel/Android.mk
@@ -29,8 +29,6 @@ include $(LOCAL_PATH)/Makefile.sources
29 29
30LOCAL_MODULE := libdrm_intel 30LOCAL_MODULE := libdrm_intel
31 31
32LOCAL_SHARED_LIBRARIES := libdrm
33
34LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_INTEL_FILES)) 32LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_INTEL_FILES))
35 33
36LOCAL_C_INCLUDES := \ 34LOCAL_C_INCLUDES := \
diff --git a/intel/Makefile.am b/intel/Makefile.am
index ca4ed84c..d0045684 100644
--- a/intel/Makefile.am
+++ b/intel/Makefile.am
@@ -26,9 +26,7 @@ include Makefile.sources
26 26
27AM_CFLAGS = \ 27AM_CFLAGS = \
28 $(WARN_CFLAGS) \ 28 $(WARN_CFLAGS) \
29 $(VISIBILITY_CFLAGS) \
30 -I$(top_srcdir) \ 29 -I$(top_srcdir) \
31 -I$(top_srcdir)/intel \
32 $(PTHREADSTUBS_CFLAGS) \ 30 $(PTHREADSTUBS_CFLAGS) \
33 $(PCIACCESS_CFLAGS) \ 31 $(PCIACCESS_CFLAGS) \
34 $(VALGRIND_CFLAGS) \ 32 $(VALGRIND_CFLAGS) \
@@ -44,8 +42,6 @@ libdrm_intel_la_LIBADD = ../libdrm.la \
44 42
45libdrm_intel_la_SOURCES = $(LIBDRM_INTEL_FILES) 43libdrm_intel_la_SOURCES = $(LIBDRM_INTEL_FILES)
46 44
47intel_bufmgr_gem_o_CFLAGS = $(AM_CFLAGS) -c99
48
49libdrm_intelincludedir = ${includedir}/libdrm 45libdrm_intelincludedir = ${includedir}/libdrm
50libdrm_intelinclude_HEADERS = $(LIBDRM_INTEL_H_FILES) 46libdrm_intelinclude_HEADERS = $(LIBDRM_INTEL_H_FILES)
51 47
@@ -61,7 +57,8 @@ BATCHES = \
61 tests/gen7-3d.batch 57 tests/gen7-3d.batch
62 58
63TESTS = \ 59TESTS = \
64 $(BATCHES:.batch=.batch.sh) 60 $(BATCHES:.batch=.batch.sh) \
61 intel-symbol-check
65 62
66EXTRA_DIST = \ 63EXTRA_DIST = \
67 $(BATCHES) \ 64 $(BATCHES) \
@@ -69,7 +66,8 @@ EXTRA_DIST = \
69 $(BATCHES:.batch=.batch-ref.txt) \ 66 $(BATCHES:.batch=.batch-ref.txt) \
70 $(BATCHES:.batch=.batch-ref.txt) \ 67 $(BATCHES:.batch=.batch-ref.txt) \
71 tests/test-batch.sh \ 68 tests/test-batch.sh \
72 Android.mk 69 Android.mk \
70 $(TESTS)
73 71
74test_decode_LDADD = libdrm_intel.la ../libdrm.la 72test_decode_LDADD = libdrm_intel.la ../libdrm.la
75 73
diff --git a/intel/intel-symbol-check b/intel/intel-symbol-check
new file mode 100755
index 00000000..bde7634c
--- /dev/null
+++ b/intel/intel-symbol-check
@@ -0,0 +1,90 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.sources/LIBDRM_INTEL_H_FILES
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_intel.so} | awk '{print $3}' | while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13drm_intel_bo_alloc
14drm_intel_bo_alloc_for_render
15drm_intel_bo_alloc_tiled
16drm_intel_bo_alloc_userptr
17drm_intel_bo_busy
18drm_intel_bo_disable_reuse
19drm_intel_bo_emit_reloc
20drm_intel_bo_emit_reloc_fence
21drm_intel_bo_exec
22drm_intel_bo_fake_alloc_static
23drm_intel_bo_fake_disable_backing_store
24drm_intel_bo_flink
25drm_intel_bo_gem_create_from_name
26drm_intel_bo_gem_create_from_prime
27drm_intel_bo_gem_export_to_prime
28drm_intel_bo_get_subdata
29drm_intel_bo_get_tiling
30drm_intel_bo_is_reusable
31drm_intel_bo_madvise
32drm_intel_bo_map
33drm_intel_bo_mrb_exec
34drm_intel_bo_pin
35drm_intel_bo_reference
36drm_intel_bo_references
37drm_intel_bo_set_softpin_offset
38drm_intel_bo_set_tiling
39drm_intel_bo_subdata
40drm_intel_bo_unmap
41drm_intel_bo_unpin
42drm_intel_bo_unreference
43drm_intel_bo_use_48b_address_range
44drm_intel_bo_wait_rendering
45drm_intel_bufmgr_check_aperture_space
46drm_intel_bufmgr_destroy
47drm_intel_bufmgr_fake_contended_lock_take
48drm_intel_bufmgr_fake_evict_all
49drm_intel_bufmgr_fake_init
50drm_intel_bufmgr_fake_set_exec_callback
51drm_intel_bufmgr_fake_set_fence_callback
52drm_intel_bufmgr_fake_set_last_dispatch
53drm_intel_bufmgr_gem_enable_fenced_relocs
54drm_intel_bufmgr_gem_enable_reuse
55drm_intel_bufmgr_gem_get_devid
56drm_intel_bufmgr_gem_init
57drm_intel_bufmgr_gem_set_aub_annotations
58drm_intel_bufmgr_gem_set_aub_dump
59drm_intel_bufmgr_gem_set_aub_filename
60drm_intel_bufmgr_gem_set_vma_cache_size
61drm_intel_bufmgr_set_debug
62drm_intel_decode
63drm_intel_decode_context_alloc
64drm_intel_decode_context_free
65drm_intel_decode_set_batch_pointer
66drm_intel_decode_set_dump_past_end
67drm_intel_decode_set_head_tail
68drm_intel_decode_set_output_file
69drm_intel_gem_bo_aub_dump_bmp
70drm_intel_gem_bo_clear_relocs
71drm_intel_gem_bo_context_exec
72drm_intel_gem_bo_get_reloc_count
73drm_intel_gem_bo_map_gtt
74drm_intel_gem_bo_map_unsynchronized
75drm_intel_gem_bo_start_gtt_access
76drm_intel_gem_bo_unmap_gtt
77drm_intel_gem_bo_wait
78drm_intel_gem_context_create
79drm_intel_gem_context_destroy
80drm_intel_get_aperture_sizes
81drm_intel_get_eu_total
82drm_intel_get_pipe_from_crtc_id
83drm_intel_get_reset_stats
84drm_intel_get_subslice_total
85drm_intel_reg_read
86EOF
87done)
88
89test ! -n "$FUNCS" || echo $FUNCS
90test ! -n "$FUNCS"
diff --git a/intel/intel_bufmgr.c b/intel/intel_bufmgr.c
index 234cd13e..a2853400 100644
--- a/intel/intel_bufmgr.c
+++ b/intel/intel_bufmgr.c
@@ -37,7 +37,7 @@
37#include <drm.h> 37#include <drm.h>
38#include <i915_drm.h> 38#include <i915_drm.h>
39#include <pciaccess.h> 39#include <pciaccess.h>
40#include "libdrm.h" 40#include "libdrm_macros.h"
41#include "intel_bufmgr.h" 41#include "intel_bufmgr.h"
42#include "intel_bufmgr_priv.h" 42#include "intel_bufmgr_priv.h"
43#include "xf86drm.h" 43#include "xf86drm.h"
@@ -47,21 +47,21 @@
47 * Convenience functions for buffer management methods. 47 * Convenience functions for buffer management methods.
48 */ 48 */
49 49
50drm_public drm_intel_bo * 50drm_intel_bo *
51drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name, 51drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
52 unsigned long size, unsigned int alignment) 52 unsigned long size, unsigned int alignment)
53{ 53{
54 return bufmgr->bo_alloc(bufmgr, name, size, alignment); 54 return bufmgr->bo_alloc(bufmgr, name, size, alignment);
55} 55}
56 56
57drm_public drm_intel_bo * 57drm_intel_bo *
58drm_intel_bo_alloc_for_render(drm_intel_bufmgr *bufmgr, const char *name, 58drm_intel_bo_alloc_for_render(drm_intel_bufmgr *bufmgr, const char *name,
59 unsigned long size, unsigned int alignment) 59 unsigned long size, unsigned int alignment)
60{ 60{
61 return bufmgr->bo_alloc_for_render(bufmgr, name, size, alignment); 61 return bufmgr->bo_alloc_for_render(bufmgr, name, size, alignment);
62} 62}
63 63
64drm_public drm_intel_bo * 64drm_intel_bo *
65drm_intel_bo_alloc_userptr(drm_intel_bufmgr *bufmgr, 65drm_intel_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
66 const char *name, void *addr, 66 const char *name, void *addr,
67 uint32_t tiling_mode, 67 uint32_t tiling_mode,
@@ -75,7 +75,7 @@ drm_intel_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
75 return NULL; 75 return NULL;
76} 76}
77 77
78drm_public drm_intel_bo * 78drm_intel_bo *
79drm_intel_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name, 79drm_intel_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
80 int x, int y, int cpp, uint32_t *tiling_mode, 80 int x, int y, int cpp, uint32_t *tiling_mode,
81 unsigned long *pitch, unsigned long flags) 81 unsigned long *pitch, unsigned long flags)
@@ -84,13 +84,13 @@ drm_intel_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
84 tiling_mode, pitch, flags); 84 tiling_mode, pitch, flags);
85} 85}
86 86
87drm_public void 87void
88drm_intel_bo_reference(drm_intel_bo *bo) 88drm_intel_bo_reference(drm_intel_bo *bo)
89{ 89{
90 bo->bufmgr->bo_reference(bo); 90 bo->bufmgr->bo_reference(bo);
91} 91}
92 92
93drm_public void 93void
94drm_intel_bo_unreference(drm_intel_bo *bo) 94drm_intel_bo_unreference(drm_intel_bo *bo)
95{ 95{
96 if (bo == NULL) 96 if (bo == NULL)
@@ -99,26 +99,26 @@ drm_intel_bo_unreference(drm_intel_bo *bo)
99 bo->bufmgr->bo_unreference(bo); 99 bo->bufmgr->bo_unreference(bo);
100} 100}
101 101
102drm_public int 102int
103drm_intel_bo_map(drm_intel_bo *buf, int write_enable) 103drm_intel_bo_map(drm_intel_bo *buf, int write_enable)
104{ 104{
105 return buf->bufmgr->bo_map(buf, write_enable); 105 return buf->bufmgr->bo_map(buf, write_enable);
106} 106}
107 107
108drm_public int 108int
109drm_intel_bo_unmap(drm_intel_bo *buf) 109drm_intel_bo_unmap(drm_intel_bo *buf)
110{ 110{
111 return buf->bufmgr->bo_unmap(buf); 111 return buf->bufmgr->bo_unmap(buf);
112} 112}
113 113
114drm_public int 114int
115drm_intel_bo_subdata(drm_intel_bo *bo, unsigned long offset, 115drm_intel_bo_subdata(drm_intel_bo *bo, unsigned long offset,
116 unsigned long size, const void *data) 116 unsigned long size, const void *data)
117{ 117{
118 return bo->bufmgr->bo_subdata(bo, offset, size, data); 118 return bo->bufmgr->bo_subdata(bo, offset, size, data);
119} 119}
120 120
121drm_public int 121int
122drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset, 122drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
123 unsigned long size, void *data) 123 unsigned long size, void *data)
124{ 124{
@@ -137,26 +137,26 @@ drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
137 return 0; 137 return 0;
138} 138}
139 139
140drm_public void 140void
141drm_intel_bo_wait_rendering(drm_intel_bo *bo) 141drm_intel_bo_wait_rendering(drm_intel_bo *bo)
142{ 142{
143 bo->bufmgr->bo_wait_rendering(bo); 143 bo->bufmgr->bo_wait_rendering(bo);
144} 144}
145 145
146drm_public void 146void
147drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr) 147drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr)
148{ 148{
149 bufmgr->destroy(bufmgr); 149 bufmgr->destroy(bufmgr);
150} 150}
151 151
152drm_public int 152int
153drm_intel_bo_exec(drm_intel_bo *bo, int used, 153drm_intel_bo_exec(drm_intel_bo *bo, int used,
154 drm_clip_rect_t * cliprects, int num_cliprects, int DR4) 154 drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
155{ 155{
156 return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4); 156 return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4);
157} 157}
158 158
159drm_public int 159int
160drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used, 160drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
161 drm_clip_rect_t *cliprects, int num_cliprects, int DR4, 161 drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
162 unsigned int rings) 162 unsigned int rings)
@@ -176,19 +176,19 @@ drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
176 } 176 }
177} 177}
178 178
179drm_public void 179void
180drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug) 180drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug)
181{ 181{
182 bufmgr->debug = enable_debug; 182 bufmgr->debug = enable_debug;
183} 183}
184 184
185drm_public int 185int
186drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count) 186drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
187{ 187{
188 return bo_array[0]->bufmgr->check_aperture_space(bo_array, count); 188 return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
189} 189}
190 190
191drm_public int 191int
192drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name) 192drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
193{ 193{
194 if (bo->bufmgr->bo_flink) 194 if (bo->bufmgr->bo_flink)
@@ -197,7 +197,7 @@ drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
197 return -ENODEV; 197 return -ENODEV;
198} 198}
199 199
200drm_public int 200int
201drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset, 201drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
202 drm_intel_bo *target_bo, uint32_t target_offset, 202 drm_intel_bo *target_bo, uint32_t target_offset,
203 uint32_t read_domains, uint32_t write_domain) 203 uint32_t read_domains, uint32_t write_domain)
@@ -208,7 +208,7 @@ drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
208} 208}
209 209
210/* For fence registers, not GL fences */ 210/* For fence registers, not GL fences */
211drm_public int 211int
212drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset, 212drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
213 drm_intel_bo *target_bo, uint32_t target_offset, 213 drm_intel_bo *target_bo, uint32_t target_offset,
214 uint32_t read_domains, uint32_t write_domain) 214 uint32_t read_domains, uint32_t write_domain)
@@ -219,7 +219,7 @@ drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
219} 219}
220 220
221 221
222drm_public int 222int
223drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment) 223drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
224{ 224{
225 if (bo->bufmgr->bo_pin) 225 if (bo->bufmgr->bo_pin)
@@ -228,7 +228,7 @@ drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
228 return -ENODEV; 228 return -ENODEV;
229} 229}
230 230
231drm_public int 231int
232drm_intel_bo_unpin(drm_intel_bo *bo) 232drm_intel_bo_unpin(drm_intel_bo *bo)
233{ 233{
234 if (bo->bufmgr->bo_unpin) 234 if (bo->bufmgr->bo_unpin)
@@ -237,7 +237,7 @@ drm_intel_bo_unpin(drm_intel_bo *bo)
237 return -ENODEV; 237 return -ENODEV;
238} 238}
239 239
240drm_public int 240int
241drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode, 241drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
242 uint32_t stride) 242 uint32_t stride)
243{ 243{
@@ -248,7 +248,7 @@ drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
248 return 0; 248 return 0;
249} 249}
250 250
251drm_public int 251int
252drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode, 252drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
253 uint32_t * swizzle_mode) 253 uint32_t * swizzle_mode)
254{ 254{
@@ -260,7 +260,16 @@ drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
260 return 0; 260 return 0;
261} 261}
262 262
263drm_public int 263int
264drm_intel_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset)
265{
266 if (bo->bufmgr->bo_set_softpin_offset)
267 return bo->bufmgr->bo_set_softpin_offset(bo, offset);
268
269 return -ENODEV;
270}
271
272int
264drm_intel_bo_disable_reuse(drm_intel_bo *bo) 273drm_intel_bo_disable_reuse(drm_intel_bo *bo)
265{ 274{
266 if (bo->bufmgr->bo_disable_reuse) 275 if (bo->bufmgr->bo_disable_reuse)
@@ -268,7 +277,7 @@ drm_intel_bo_disable_reuse(drm_intel_bo *bo)
268 return 0; 277 return 0;
269} 278}
270 279
271drm_public int 280int
272drm_intel_bo_is_reusable(drm_intel_bo *bo) 281drm_intel_bo_is_reusable(drm_intel_bo *bo)
273{ 282{
274 if (bo->bufmgr->bo_is_reusable) 283 if (bo->bufmgr->bo_is_reusable)
@@ -276,7 +285,7 @@ drm_intel_bo_is_reusable(drm_intel_bo *bo)
276 return 0; 285 return 0;
277} 286}
278 287
279drm_public int 288int
280drm_intel_bo_busy(drm_intel_bo *bo) 289drm_intel_bo_busy(drm_intel_bo *bo)
281{ 290{
282 if (bo->bufmgr->bo_busy) 291 if (bo->bufmgr->bo_busy)
@@ -284,7 +293,7 @@ drm_intel_bo_busy(drm_intel_bo *bo)
284 return 0; 293 return 0;
285} 294}
286 295
287drm_public int 296int
288drm_intel_bo_madvise(drm_intel_bo *bo, int madv) 297drm_intel_bo_madvise(drm_intel_bo *bo, int madv)
289{ 298{
290 if (bo->bufmgr->bo_madvise) 299 if (bo->bufmgr->bo_madvise)
@@ -292,13 +301,24 @@ drm_intel_bo_madvise(drm_intel_bo *bo, int madv)
292 return -1; 301 return -1;
293} 302}
294 303
295drm_public int 304int
305drm_intel_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
306{
307 if (bo->bufmgr->bo_use_48b_address_range) {
308 bo->bufmgr->bo_use_48b_address_range(bo, enable);
309 return 0;
310 }
311
312 return -ENODEV;
313}
314
315int
296drm_intel_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo) 316drm_intel_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
297{ 317{
298 return bo->bufmgr->bo_references(bo, target_bo); 318 return bo->bufmgr->bo_references(bo, target_bo);
299} 319}
300 320
301drm_public int 321int
302drm_intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id) 322drm_intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id)
303{ 323{
304 if (bufmgr->get_pipe_from_crtc_id) 324 if (bufmgr->get_pipe_from_crtc_id)
@@ -332,7 +352,7 @@ err:
332 return size; 352 return size;
333} 353}
334 354
335drm_public int 355int
336drm_intel_get_aperture_sizes(int fd, size_t *mappable, size_t *total) 356drm_intel_get_aperture_sizes(int fd, size_t *mappable, size_t *total)
337{ 357{
338 358
diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h
index be83a56a..a1abbcd2 100644
--- a/intel/intel_bufmgr.h
+++ b/intel/intel_bufmgr.h
@@ -38,6 +38,10 @@
38#include <stdint.h> 38#include <stdint.h>
39#include <stdio.h> 39#include <stdio.h>
40 40
41#if defined(__cplusplus)
42extern "C" {
43#endif
44
41struct drm_clip_rect; 45struct drm_clip_rect;
42 46
43typedef struct _drm_intel_bufmgr drm_intel_bufmgr; 47typedef struct _drm_intel_bufmgr drm_intel_bufmgr;
@@ -160,6 +164,8 @@ int drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
160int drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name); 164int drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name);
161int drm_intel_bo_busy(drm_intel_bo *bo); 165int drm_intel_bo_busy(drm_intel_bo *bo);
162int drm_intel_bo_madvise(drm_intel_bo *bo, int madv); 166int drm_intel_bo_madvise(drm_intel_bo *bo, int madv);
167int drm_intel_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable);
168int drm_intel_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset);
163 169
164int drm_intel_bo_disable_reuse(drm_intel_bo *bo); 170int drm_intel_bo_disable_reuse(drm_intel_bo *bo);
165int drm_intel_bo_is_reusable(drm_intel_bo *bo); 171int drm_intel_bo_is_reusable(drm_intel_bo *bo);
@@ -264,6 +270,9 @@ int drm_intel_get_reset_stats(drm_intel_context *ctx,
264 uint32_t *active, 270 uint32_t *active,
265 uint32_t *pending); 271 uint32_t *pending);
266 272
273int drm_intel_get_subslice_total(int fd, unsigned int *subslice_total);
274int drm_intel_get_eu_total(int fd, unsigned int *eu_total);
275
267/** @{ Compatibility defines to keep old code building despite the symbol rename 276/** @{ Compatibility defines to keep old code building despite the symbol rename
268 * from dri_* to drm_intel_* 277 * from dri_* to drm_intel_*
269 */ 278 */
@@ -305,4 +314,8 @@ int drm_intel_get_reset_stats(drm_intel_context *ctx,
305 314
306/** @{ */ 315/** @{ */
307 316
317#if defined(__cplusplus)
318}
319#endif
320
308#endif /* INTEL_BUFMGR_H */ 321#endif /* INTEL_BUFMGR_H */
diff --git a/intel/intel_bufmgr_fake.c b/intel/intel_bufmgr_fake.c
index c4828faa..7f4c7b9f 100644
--- a/intel/intel_bufmgr_fake.c
+++ b/intel/intel_bufmgr_fake.c
@@ -42,6 +42,7 @@
42#include <string.h> 42#include <string.h>
43#include <assert.h> 43#include <assert.h>
44#include <errno.h> 44#include <errno.h>
45#include <strings.h>
45#include <xf86drm.h> 46#include <xf86drm.h>
46#include <pthread.h> 47#include <pthread.h>
47#include "intel_bufmgr.h" 48#include "intel_bufmgr.h"
@@ -49,14 +50,9 @@
49#include "drm.h" 50#include "drm.h"
50#include "i915_drm.h" 51#include "i915_drm.h"
51#include "mm.h" 52#include "mm.h"
52#include "libdrm.h" 53#include "libdrm_macros.h"
53#include "libdrm_lists.h" 54#include "libdrm_lists.h"
54 55
55/* Support gcc's __FUNCTION__ for people using other compilers */
56#if !defined(__GNUC__) && !defined(__FUNCTION__)
57# define __FUNCTION__ __func__ /* C99 */
58#endif
59
60#define DBG(...) do { \ 56#define DBG(...) do { \
61 if (bufmgr_fake->bufmgr.debug) \ 57 if (bufmgr_fake->bufmgr.debug) \
62 drmMsg(__VA_ARGS__); \ 58 drmMsg(__VA_ARGS__); \
@@ -249,7 +245,7 @@ FENCE_LTE(unsigned a, unsigned b)
249 return 0; 245 return 0;
250} 246}
251 247
252drm_public void 248void
253drm_intel_bufmgr_fake_set_fence_callback(drm_intel_bufmgr *bufmgr, 249drm_intel_bufmgr_fake_set_fence_callback(drm_intel_bufmgr *bufmgr,
254 unsigned int (*emit) (void *priv), 250 unsigned int (*emit) (void *priv),
255 void (*wait) (unsigned int fence, 251 void (*wait) (unsigned int fence,
@@ -278,7 +274,7 @@ _fence_emit_internal(drm_intel_bufmgr_fake *bufmgr_fake)
278 ret = drmCommandWriteRead(bufmgr_fake->fd, DRM_I915_IRQ_EMIT, 274 ret = drmCommandWriteRead(bufmgr_fake->fd, DRM_I915_IRQ_EMIT,
279 &ie, sizeof(ie)); 275 &ie, sizeof(ie));
280 if (ret) { 276 if (ret) {
281 drmMsg("%s: drm_i915_irq_emit: %d\n", __FUNCTION__, ret); 277 drmMsg("%s: drm_i915_irq_emit: %d\n", __func__, ret);
282 abort(); 278 abort();
283 } 279 }
284 280
@@ -545,7 +541,7 @@ evict_lru(drm_intel_bufmgr_fake *bufmgr_fake, unsigned int max_fence)
545{ 541{
546 struct block *block, *tmp; 542 struct block *block, *tmp;
547 543
548 DBG("%s\n", __FUNCTION__); 544 DBG("%s\n", __func__);
549 545
550 DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->lru) { 546 DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->lru) {
551 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo; 547 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
@@ -572,7 +568,7 @@ evict_mru(drm_intel_bufmgr_fake *bufmgr_fake)
572{ 568{
573 struct block *block, *tmp; 569 struct block *block, *tmp;
574 570
575 DBG("%s\n", __FUNCTION__); 571 DBG("%s\n", __func__);
576 572
577 DRMLISTFOREACHSAFEREVERSE(block, tmp, &bufmgr_fake->lru) { 573 DRMLISTFOREACHSAFEREVERSE(block, tmp, &bufmgr_fake->lru) {
578 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo; 574 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
@@ -632,7 +628,7 @@ clear_fenced(drm_intel_bufmgr_fake *bufmgr_fake, unsigned int fence_cookie)
632 } 628 }
633 } 629 }
634 630
635 DBG("%s: %d\n", __FUNCTION__, ret); 631 DBG("%s: %d\n", __func__, ret);
636 return ret; 632 return ret;
637} 633}
638 634
@@ -717,7 +713,7 @@ evict_and_alloc_block(drm_intel_bo *bo)
717 if (alloc_block(bo)) 713 if (alloc_block(bo))
718 return 1; 714 return 1;
719 715
720 DBG("%s 0x%lx bytes failed\n", __FUNCTION__, bo->size); 716 DBG("%s 0x%lx bytes failed\n", __func__, bo->size);
721 717
722 return 0; 718 return 0;
723} 719}
@@ -772,7 +768,7 @@ drm_intel_fake_bo_wait_rendering(drm_intel_bo *bo)
772 * -- just evict everything 768 * -- just evict everything
773 * -- and wait for idle 769 * -- and wait for idle
774 */ 770 */
775drm_public void 771void
776drm_intel_bufmgr_fake_contended_lock_take(drm_intel_bufmgr *bufmgr) 772drm_intel_bufmgr_fake_contended_lock_take(drm_intel_bufmgr *bufmgr)
777{ 773{
778 drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr; 774 drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
@@ -868,7 +864,7 @@ drm_intel_fake_bo_alloc_tiled(drm_intel_bufmgr * bufmgr,
868 4096); 864 4096);
869} 865}
870 866
871drm_public drm_intel_bo * 867drm_intel_bo *
872drm_intel_bo_fake_alloc_static(drm_intel_bufmgr *bufmgr, 868drm_intel_bo_fake_alloc_static(drm_intel_bufmgr *bufmgr,
873 const char *name, 869 const char *name,
874 unsigned long offset, 870 unsigned long offset,
@@ -963,7 +959,7 @@ drm_intel_fake_bo_unreference(drm_intel_bo *bo)
963 * Set the buffer as not requiring backing store, and instead get the callback 959 * Set the buffer as not requiring backing store, and instead get the callback
964 * invoked whenever it would be set dirty. 960 * invoked whenever it would be set dirty.
965 */ 961 */
966drm_public void 962void
967drm_intel_bo_fake_disable_backing_store(drm_intel_bo *bo, 963drm_intel_bo_fake_disable_backing_store(drm_intel_bo *bo,
968 void (*invalidate_cb) (drm_intel_bo *bo, 964 void (*invalidate_cb) (drm_intel_bo *bo,
969 void *ptr), 965 void *ptr),
@@ -1027,12 +1023,12 @@ static int
1027 bo_fake->name, bo_fake->bo.size / 1024); 1023 bo_fake->name, bo_fake->bo.size / 1024);
1028 1024
1029 if (bo->virtual != NULL) { 1025 if (bo->virtual != NULL) {
1030 drmMsg("%s: already mapped\n", __FUNCTION__); 1026 drmMsg("%s: already mapped\n", __func__);
1031 abort(); 1027 abort();
1032 } else if (bo_fake->flags & (BM_NO_BACKING_STORE | BM_PINNED)) { 1028 } else if (bo_fake->flags & (BM_NO_BACKING_STORE | BM_PINNED)) {
1033 1029
1034 if (!bo_fake->block && !evict_and_alloc_block(bo)) { 1030 if (!bo_fake->block && !evict_and_alloc_block(bo)) {
1035 DBG("%s: alloc failed\n", __FUNCTION__); 1031 DBG("%s: alloc failed\n", __func__);
1036 bufmgr_fake->fail = 1; 1032 bufmgr_fake->fail = 1;
1037 return 1; 1033 return 1;
1038 } else { 1034 } else {
@@ -1417,7 +1413,7 @@ drm_intel_bo_fake_post_submit(drm_intel_bo *bo)
1417 bo_fake->write_domain = 0; 1413 bo_fake->write_domain = 0;
1418} 1414}
1419 1415
1420drm_public void 1416void
1421drm_intel_bufmgr_fake_set_exec_callback(drm_intel_bufmgr *bufmgr, 1417drm_intel_bufmgr_fake_set_exec_callback(drm_intel_bufmgr *bufmgr,
1422 int (*exec) (drm_intel_bo *bo, 1418 int (*exec) (drm_intel_bo *bo,
1423 unsigned int used, 1419 unsigned int used,
@@ -1465,7 +1461,7 @@ restart:
1465 assert(ret == 0); 1461 assert(ret == 0);
1466 1462
1467 if (bufmgr_fake->exec != NULL) { 1463 if (bufmgr_fake->exec != NULL) {
1468 int ret = bufmgr_fake->exec(bo, used, bufmgr_fake->exec_priv); 1464 ret = bufmgr_fake->exec(bo, used, bufmgr_fake->exec_priv);
1469 if (ret != 0) { 1465 if (ret != 0) {
1470 pthread_mutex_unlock(&bufmgr_fake->lock); 1466 pthread_mutex_unlock(&bufmgr_fake->lock);
1471 return ret; 1467 return ret;
@@ -1540,7 +1536,7 @@ drm_intel_fake_check_aperture_space(drm_intel_bo ** bo_array, int count)
1540 * Used by the X Server on LeaveVT, when the card memory is no longer our 1536 * Used by the X Server on LeaveVT, when the card memory is no longer our
1541 * own. 1537 * own.
1542 */ 1538 */
1543drm_public void 1539void
1544drm_intel_bufmgr_fake_evict_all(drm_intel_bufmgr *bufmgr) 1540drm_intel_bufmgr_fake_evict_all(drm_intel_bufmgr *bufmgr)
1545{ 1541{
1546 drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr; 1542 drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
@@ -1575,7 +1571,7 @@ drm_intel_bufmgr_fake_evict_all(drm_intel_bufmgr *bufmgr)
1575 pthread_mutex_unlock(&bufmgr_fake->lock); 1571 pthread_mutex_unlock(&bufmgr_fake->lock);
1576} 1572}
1577 1573
1578drm_public void 1574void
1579drm_intel_bufmgr_fake_set_last_dispatch(drm_intel_bufmgr *bufmgr, 1575drm_intel_bufmgr_fake_set_last_dispatch(drm_intel_bufmgr *bufmgr,
1580 volatile unsigned int 1576 volatile unsigned int
1581 *last_dispatch) 1577 *last_dispatch)
@@ -1585,7 +1581,7 @@ drm_intel_bufmgr_fake_set_last_dispatch(drm_intel_bufmgr *bufmgr,
1585 bufmgr_fake->last_dispatch = (volatile int *)last_dispatch; 1581 bufmgr_fake->last_dispatch = (volatile int *)last_dispatch;
1586} 1582}
1587 1583
1588drm_public drm_intel_bufmgr * 1584drm_intel_bufmgr *
1589drm_intel_bufmgr_fake_init(int fd, unsigned long low_offset, 1585drm_intel_bufmgr_fake_init(int fd, unsigned long low_offset,
1590 void *low_virtual, unsigned long size, 1586 void *low_virtual, unsigned long size,
1591 volatile unsigned int *last_dispatch) 1587 volatile unsigned int *last_dispatch)
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index cf85bb8a..dc28200f 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -56,12 +56,11 @@
56#ifndef ETIME 56#ifndef ETIME
57#define ETIME ETIMEDOUT 57#define ETIME ETIMEDOUT
58#endif 58#endif
59#include "libdrm.h" 59#include "libdrm_macros.h"
60#include "libdrm_lists.h" 60#include "libdrm_lists.h"
61#include "intel_bufmgr.h" 61#include "intel_bufmgr.h"
62#include "intel_bufmgr_priv.h" 62#include "intel_bufmgr_priv.h"
63#include "intel_chipset.h" 63#include "intel_chipset.h"
64#include "intel_aub.h"
65#include "string.h" 64#include "string.h"
66 65
67#include "i915_drm.h" 66#include "i915_drm.h"
@@ -74,7 +73,7 @@
74#define VG(x) 73#define VG(x)
75#endif 74#endif
76 75
77#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s))) 76#define memclear(s) memset(&s, 0, sizeof(s))
78 77
79#define DBG(...) do { \ 78#define DBG(...) do { \
80 if (bufmgr_gem->bufmgr.debug) \ 79 if (bufmgr_gem->bufmgr.debug) \
@@ -82,6 +81,23 @@
82} while (0) 81} while (0)
83 82
84#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 83#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
84#define MAX2(A, B) ((A) > (B) ? (A) : (B))
85
86/**
87 * upper_32_bits - return bits 32-63 of a number
88 * @n: the number we're accessing
89 *
90 * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress
91 * the "right shift count >= width of type" warning when that quantity is
92 * 32-bits.
93 */
94#define upper_32_bits(n) ((__u32)(((n) >> 16) >> 16))
95
96/**
97 * lower_32_bits - return bits 0-31 of a number
98 * @n: the number we're accessing
99 */
100#define lower_32_bits(n) ((__u32)(n))
85 101
86typedef struct _drm_intel_bo_gem drm_intel_bo_gem; 102typedef struct _drm_intel_bo_gem drm_intel_bo_gem;
87 103
@@ -132,9 +148,11 @@ typedef struct _drm_intel_bufmgr_gem {
132 unsigned int has_vebox : 1; 148 unsigned int has_vebox : 1;
133 bool fenced_relocs; 149 bool fenced_relocs;
134 150
135 char *aub_filename; 151 struct {
136 FILE *aub_file; 152 void *ptr;
137 uint32_t aub_offset; 153 uint32_t handle;
154 } userptr_active;
155
138} drm_intel_bufmgr_gem; 156} drm_intel_bufmgr_gem;
139 157
140#define DRM_INTEL_RELOC_FENCE (1<<0) 158#define DRM_INTEL_RELOC_FENCE (1<<0)
@@ -182,6 +200,13 @@ struct _drm_intel_bo_gem {
182 drm_intel_reloc_target *reloc_target_info; 200 drm_intel_reloc_target *reloc_target_info;
183 /** Number of entries in relocs */ 201 /** Number of entries in relocs */
184 int reloc_count; 202 int reloc_count;
203 /** Array of BOs that are referenced by this buffer and will be softpinned */
204 drm_intel_bo **softpin_target;
205 /** Number softpinned BOs that are referenced by this buffer */
206 int softpin_target_count;
207 /** Maximum amount of softpinned BOs that are referenced by this buffer */
208 int softpin_target_size;
209
185 /** Mapped address for the buffer, saved across map/unmap cycles */ 210 /** Mapped address for the buffer, saved across map/unmap cycles */
186 void *mem_virtual; 211 void *mem_virtual;
187 /** GTT virtual address for the buffer, saved across map/unmap cycles */ 212 /** GTT virtual address for the buffer, saved across map/unmap cycles */
@@ -235,6 +260,20 @@ struct _drm_intel_bo_gem {
235 bool is_userptr; 260 bool is_userptr;
236 261
237 /** 262 /**
263 * Boolean of whether this buffer can be placed in the full 48-bit
264 * address range on gen8+.
265 *
266 * By default, buffers will be keep in a 32-bit range, unless this
267 * flag is explicitly set.
268 */
269 bool use_48b_address_range;
270
271 /**
272 * Whether this buffer is softpinned at offset specified by the user
273 */
274 bool is_softpin;
275
276 /**
238 * Size in bytes of this buffer and its relocation descendents. 277 * Size in bytes of this buffer and its relocation descendents.
239 * 278 *
240 * Used to avoid costly tree walking in 279 * Used to avoid costly tree walking in
@@ -250,11 +289,6 @@ struct _drm_intel_bo_gem {
250 289
251 /** Flags that we may need to do the SW_FINSIH ioctl on unmap. */ 290 /** Flags that we may need to do the SW_FINSIH ioctl on unmap. */
252 bool mapped_cpu_write; 291 bool mapped_cpu_write;
253
254 uint32_t aub_offset;
255
256 drm_intel_aub_annotation *aub_annotations;
257 unsigned aub_annotation_count;
258}; 292};
259 293
260static unsigned int 294static unsigned int
@@ -279,6 +313,11 @@ static void drm_intel_gem_bo_unreference(drm_intel_bo *bo);
279 313
280static void drm_intel_gem_bo_free(drm_intel_bo *bo); 314static void drm_intel_gem_bo_free(drm_intel_bo *bo);
281 315
316static inline drm_intel_bo_gem *to_bo_gem(drm_intel_bo *bo)
317{
318 return (drm_intel_bo_gem *)bo;
319}
320
282static unsigned long 321static unsigned long
283drm_intel_gem_bo_tile_size(drm_intel_bufmgr_gem *bufmgr_gem, unsigned long size, 322drm_intel_gem_bo_tile_size(drm_intel_bufmgr_gem *bufmgr_gem, unsigned long size,
284 uint32_t *tiling_mode) 323 uint32_t *tiling_mode)
@@ -387,8 +426,9 @@ drm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
387 drm_intel_bo *bo = bufmgr_gem->exec_bos[i]; 426 drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
388 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; 427 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
389 428
390 if (bo_gem->relocs == NULL) { 429 if (bo_gem->relocs == NULL && bo_gem->softpin_target == NULL) {
391 DBG("%2d: %d (%s)\n", i, bo_gem->gem_handle, 430 DBG("%2d: %d %s(%s)\n", i, bo_gem->gem_handle,
431 bo_gem->is_softpin ? "*" : "",
392 bo_gem->name); 432 bo_gem->name);
393 continue; 433 continue;
394 } 434 }
@@ -398,16 +438,36 @@ drm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
398 drm_intel_bo_gem *target_gem = 438 drm_intel_bo_gem *target_gem =
399 (drm_intel_bo_gem *) target_bo; 439 (drm_intel_bo_gem *) target_bo;
400 440
401 DBG("%2d: %d (%s)@0x%08llx -> " 441 DBG("%2d: %d %s(%s)@0x%08x %08x -> "
402 "%d (%s)@0x%08lx + 0x%08x\n", 442 "%d (%s)@0x%08x %08x + 0x%08x\n",
403 i, 443 i,
404 bo_gem->gem_handle, bo_gem->name, 444 bo_gem->gem_handle,
405 (unsigned long long)bo_gem->relocs[j].offset, 445 bo_gem->is_softpin ? "*" : "",
446 bo_gem->name,
447 upper_32_bits(bo_gem->relocs[j].offset),
448 lower_32_bits(bo_gem->relocs[j].offset),
406 target_gem->gem_handle, 449 target_gem->gem_handle,
407 target_gem->name, 450 target_gem->name,
408 target_bo->offset64, 451 upper_32_bits(target_bo->offset64),
452 lower_32_bits(target_bo->offset64),
409 bo_gem->relocs[j].delta); 453 bo_gem->relocs[j].delta);
410 } 454 }
455
456 for (j = 0; j < bo_gem->softpin_target_count; j++) {
457 drm_intel_bo *target_bo = bo_gem->softpin_target[j];
458 drm_intel_bo_gem *target_gem =
459 (drm_intel_bo_gem *) target_bo;
460 DBG("%2d: %d %s(%s) -> "
461 "%d *(%s)@0x%08x %08x\n",
462 i,
463 bo_gem->gem_handle,
464 bo_gem->is_softpin ? "*" : "",
465 bo_gem->name,
466 target_gem->gem_handle,
467 target_gem->name,
468 upper_32_bits(target_bo->offset64),
469 lower_32_bits(target_bo->offset64));
470 }
411 } 471 }
412} 472}
413 473
@@ -459,7 +519,7 @@ drm_intel_add_validate_buffer(drm_intel_bo *bo)
459 bufmgr_gem->exec_objects[index].handle = bo_gem->gem_handle; 519 bufmgr_gem->exec_objects[index].handle = bo_gem->gem_handle;
460 bufmgr_gem->exec_objects[index].relocation_count = bo_gem->reloc_count; 520 bufmgr_gem->exec_objects[index].relocation_count = bo_gem->reloc_count;
461 bufmgr_gem->exec_objects[index].relocs_ptr = (uintptr_t) bo_gem->relocs; 521 bufmgr_gem->exec_objects[index].relocs_ptr = (uintptr_t) bo_gem->relocs;
462 bufmgr_gem->exec_objects[index].alignment = 0; 522 bufmgr_gem->exec_objects[index].alignment = bo->align;
463 bufmgr_gem->exec_objects[index].offset = 0; 523 bufmgr_gem->exec_objects[index].offset = 0;
464 bufmgr_gem->exec_bos[index] = bo; 524 bufmgr_gem->exec_bos[index] = bo;
465 bufmgr_gem->exec_count++; 525 bufmgr_gem->exec_count++;
@@ -471,11 +531,17 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
471 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr; 531 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
472 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo; 532 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
473 int index; 533 int index;
534 int flags = 0;
535
536 if (need_fence)
537 flags |= EXEC_OBJECT_NEEDS_FENCE;
538 if (bo_gem->use_48b_address_range)
539 flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
540 if (bo_gem->is_softpin)
541 flags |= EXEC_OBJECT_PINNED;
474 542
475 if (bo_gem->validate_index != -1) { 543 if (bo_gem->validate_index != -1) {
476 if (need_fence) 544 bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |= flags;
477 bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |=
478 EXEC_OBJECT_NEEDS_FENCE;
479 return; 545 return;
480 } 546 }
481 547
@@ -501,16 +567,13 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
501 bufmgr_gem->exec2_objects[index].handle = bo_gem->gem_handle; 567 bufmgr_gem->exec2_objects[index].handle = bo_gem->gem_handle;
502 bufmgr_gem->exec2_objects[index].relocation_count = bo_gem->reloc_count; 568 bufmgr_gem->exec2_objects[index].relocation_count = bo_gem->reloc_count;
503 bufmgr_gem->exec2_objects[index].relocs_ptr = (uintptr_t)bo_gem->relocs; 569 bufmgr_gem->exec2_objects[index].relocs_ptr = (uintptr_t)bo_gem->relocs;
504 bufmgr_gem->exec2_objects[index].alignment = 0; 570 bufmgr_gem->exec2_objects[index].alignment = bo->align;
505 bufmgr_gem->exec2_objects[index].offset = 0; 571 bufmgr_gem->exec2_objects[index].offset = bo_gem->is_softpin ?
572 bo->offset64 : 0;
506 bufmgr_gem->exec_bos[index] = bo; 573 bufmgr_gem->exec_bos[index] = bo;
507 bufmgr_gem->exec2_objects[index].flags = 0; 574 bufmgr_gem->exec2_objects[index].flags = flags;
508 bufmgr_gem->exec2_objects[index].rsvd1 = 0; 575 bufmgr_gem->exec2_objects[index].rsvd1 = 0;
509 bufmgr_gem->exec2_objects[index].rsvd2 = 0; 576 bufmgr_gem->exec2_objects[index].rsvd2 = 0;
510 if (need_fence) {
511 bufmgr_gem->exec2_objects[index].flags |=
512 EXEC_OBJECT_NEEDS_FENCE;
513 }
514 bufmgr_gem->exec_count++; 577 bufmgr_gem->exec_count++;
515} 578}
516 579
@@ -519,9 +582,10 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
519 582
520static void 583static void
521drm_intel_bo_gem_set_in_aperture_size(drm_intel_bufmgr_gem *bufmgr_gem, 584drm_intel_bo_gem_set_in_aperture_size(drm_intel_bufmgr_gem *bufmgr_gem,
522 drm_intel_bo_gem *bo_gem) 585 drm_intel_bo_gem *bo_gem,
586 unsigned int alignment)
523{ 587{
524 int size; 588 unsigned int size;
525 589
526 assert(!bo_gem->used_as_reloc_target); 590 assert(!bo_gem->used_as_reloc_target);
527 591
@@ -533,7 +597,7 @@ drm_intel_bo_gem_set_in_aperture_size(drm_intel_bufmgr_gem *bufmgr_gem,
533 */ 597 */
534 size = bo_gem->bo.size; 598 size = bo_gem->bo.size;
535 if (bufmgr_gem->gen < 4 && bo_gem->tiling_mode != I915_TILING_NONE) { 599 if (bufmgr_gem->gen < 4 && bo_gem->tiling_mode != I915_TILING_NONE) {
536 int min_size; 600 unsigned int min_size;
537 601
538 if (bufmgr_gem->has_relaxed_fencing) { 602 if (bufmgr_gem->has_relaxed_fencing) {
539 if (bufmgr_gem->gen == 3) 603 if (bufmgr_gem->gen == 3)
@@ -547,10 +611,10 @@ drm_intel_bo_gem_set_in_aperture_size(drm_intel_bufmgr_gem *bufmgr_gem,
547 min_size = size; 611 min_size = size;
548 612
549 /* Account for worst-case alignment. */ 613 /* Account for worst-case alignment. */
550 size = 2 * min_size; 614 alignment = MAX2(alignment, min_size);
551 } 615 }
552 616
553 bo_gem->reloc_tree_size = size; 617 bo_gem->reloc_tree_size = size + alignment;
554} 618}
555 619
556static int 620static int
@@ -593,7 +657,7 @@ drm_intel_gem_bo_busy(drm_intel_bo *bo)
593 if (bo_gem->reusable && bo_gem->idle) 657 if (bo_gem->reusable && bo_gem->idle)
594 return false; 658 return false;
595 659
596 VG_CLEAR(busy); 660 memclear(busy);
597 busy.handle = bo_gem->gem_handle; 661 busy.handle = bo_gem->gem_handle;
598 662
599 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy); 663 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
@@ -612,7 +676,7 @@ drm_intel_gem_bo_madvise_internal(drm_intel_bufmgr_gem *bufmgr_gem,
612{ 676{
613 struct drm_i915_gem_madvise madv; 677 struct drm_i915_gem_madvise madv;
614 678
615 VG_CLEAR(madv); 679 memclear(madv);
616 madv.handle = bo_gem->gem_handle; 680 madv.handle = bo_gem->gem_handle;
617 madv.madv = state; 681 madv.madv = state;
618 madv.retained = 1; 682 madv.retained = 1;
@@ -655,7 +719,8 @@ drm_intel_gem_bo_alloc_internal(drm_intel_bufmgr *bufmgr,
655 unsigned long size, 719 unsigned long size,
656 unsigned long flags, 720 unsigned long flags,
657 uint32_t tiling_mode, 721 uint32_t tiling_mode,
658 unsigned long stride) 722 unsigned long stride,
723 unsigned int alignment)
659{ 724{
660 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr; 725 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
661 drm_intel_bo_gem *bo_gem; 726 drm_intel_bo_gem *bo_gem;
@@ -697,7 +762,9 @@ retry:
697 bucket->head.prev, head); 762 bucket->head.prev, head);
698 DRMLISTDEL(&bo_gem->head); 763 DRMLISTDEL(&bo_gem->head);
699 alloc_from_cache = true; 764 alloc_from_cache = true;
765 bo_gem->bo.align = alignment;
700 } else { 766 } else {
767 assert(alignment == 0);
701 /* For non-render-target BOs (where we're probably 768 /* For non-render-target BOs (where we're probably
702 * going to map it first thing in order to fill it 769 * going to map it first thing in order to fill it
703 * with data), check if the last BO in the cache is 770 * with data), check if the last BO in the cache is
@@ -741,7 +808,7 @@ retry:
741 808
742 bo_gem->bo.size = bo_size; 809 bo_gem->bo.size = bo_size;
743 810
744 VG_CLEAR(create); 811 memclear(create);
745 create.size = bo_size; 812 create.size = bo_size;
746 813
747 ret = drmIoctl(bufmgr_gem->fd, 814 ret = drmIoctl(bufmgr_gem->fd,
@@ -754,6 +821,7 @@ retry:
754 return NULL; 821 return NULL;
755 } 822 }
756 bo_gem->bo.bufmgr = bufmgr; 823 bo_gem->bo.bufmgr = bufmgr;
824 bo_gem->bo.align = alignment;
757 825
758 bo_gem->tiling_mode = I915_TILING_NONE; 826 bo_gem->tiling_mode = I915_TILING_NONE;
759 bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; 827 bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
@@ -778,10 +846,9 @@ retry:
778 bo_gem->used_as_reloc_target = false; 846 bo_gem->used_as_reloc_target = false;
779 bo_gem->has_error = false; 847 bo_gem->has_error = false;
780 bo_gem->reusable = true; 848 bo_gem->reusable = true;
781 bo_gem->aub_annotations = NULL; 849 bo_gem->use_48b_address_range = false;
782 bo_gem->aub_annotation_count = 0;
783 850
784 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem); 851 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, alignment);
785 852
786 DBG("bo_create: buf %d (%s) %ldb\n", 853 DBG("bo_create: buf %d (%s) %ldb\n",
787 bo_gem->gem_handle, bo_gem->name, size); 854 bo_gem->gem_handle, bo_gem->name, size);
@@ -797,7 +864,8 @@ drm_intel_gem_bo_alloc_for_render(drm_intel_bufmgr *bufmgr,
797{ 864{
798 return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, 865 return drm_intel_gem_bo_alloc_internal(bufmgr, name, size,
799 BO_ALLOC_FOR_RENDER, 866 BO_ALLOC_FOR_RENDER,
800 I915_TILING_NONE, 0); 867 I915_TILING_NONE, 0,
868 alignment);
801} 869}
802 870
803static drm_intel_bo * 871static drm_intel_bo *
@@ -807,7 +875,7 @@ drm_intel_gem_bo_alloc(drm_intel_bufmgr *bufmgr,
807 unsigned int alignment) 875 unsigned int alignment)
808{ 876{
809 return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, 0, 877 return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, 0,
810 I915_TILING_NONE, 0); 878 I915_TILING_NONE, 0, 0);
811} 879}
812 880
813static drm_intel_bo * 881static drm_intel_bo *
@@ -859,7 +927,7 @@ drm_intel_gem_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
859 stride = 0; 927 stride = 0;
860 928
861 return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, flags, 929 return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, flags,
862 tiling, stride); 930 tiling, stride, 0);
863} 931}
864 932
865static drm_intel_bo * 933static drm_intel_bo *
@@ -888,7 +956,7 @@ drm_intel_gem_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
888 956
889 bo_gem->bo.size = size; 957 bo_gem->bo.size = size;
890 958
891 VG_CLEAR(userptr); 959 memclear(userptr);
892 userptr.user_ptr = (__u64)((unsigned long)addr); 960 userptr.user_ptr = (__u64)((unsigned long)addr);
893 userptr.user_size = size; 961 userptr.user_size = size;
894 userptr.flags = flags; 962 userptr.flags = flags;
@@ -925,8 +993,9 @@ drm_intel_gem_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
925 bo_gem->used_as_reloc_target = false; 993 bo_gem->used_as_reloc_target = false;
926 bo_gem->has_error = false; 994 bo_gem->has_error = false;
927 bo_gem->reusable = false; 995 bo_gem->reusable = false;
996 bo_gem->use_48b_address_range = false;
928 997
929 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem); 998 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
930 999
931 DBG("bo_create_userptr: " 1000 DBG("bo_create_userptr: "
932 "ptr %p buf %d (%s) size %ldb, stride 0x%x, tile mode %d\n", 1001 "ptr %p buf %d (%s) size %ldb, stride 0x%x, tile mode %d\n",
@@ -936,13 +1005,77 @@ drm_intel_gem_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
936 return &bo_gem->bo; 1005 return &bo_gem->bo;
937} 1006}
938 1007
1008static bool
1009has_userptr(drm_intel_bufmgr_gem *bufmgr_gem)
1010{
1011 int ret;
1012 void *ptr;
1013 long pgsz;
1014 struct drm_i915_gem_userptr userptr;
1015
1016 pgsz = sysconf(_SC_PAGESIZE);
1017 assert(pgsz > 0);
1018
1019 ret = posix_memalign(&ptr, pgsz, pgsz);
1020 if (ret) {
1021 DBG("Failed to get a page (%ld) for userptr detection!\n",
1022 pgsz);
1023 return false;
1024 }
1025
1026 memclear(userptr);
1027 userptr.user_ptr = (__u64)(unsigned long)ptr;
1028 userptr.user_size = pgsz;
1029
1030retry:
1031 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_USERPTR, &userptr);
1032 if (ret) {
1033 if (errno == ENODEV && userptr.flags == 0) {
1034 userptr.flags = I915_USERPTR_UNSYNCHRONIZED;
1035 goto retry;
1036 }
1037 free(ptr);
1038 return false;
1039 }
1040
1041 /* We don't release the userptr bo here as we want to keep the
1042 * kernel mm tracking alive for our lifetime. The first time we
1043 * create a userptr object the kernel has to install a mmu_notifer
1044 * which is a heavyweight operation (e.g. it requires taking all
1045 * mm_locks and stop_machine()).
1046 */
1047
1048 bufmgr_gem->userptr_active.ptr = ptr;
1049 bufmgr_gem->userptr_active.handle = userptr.handle;
1050
1051 return true;
1052}
1053
1054static drm_intel_bo *
1055check_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
1056 const char *name,
1057 void *addr,
1058 uint32_t tiling_mode,
1059 uint32_t stride,
1060 unsigned long size,
1061 unsigned long flags)
1062{
1063 if (has_userptr((drm_intel_bufmgr_gem *)bufmgr))
1064 bufmgr->bo_alloc_userptr = drm_intel_gem_bo_alloc_userptr;
1065 else
1066 bufmgr->bo_alloc_userptr = NULL;
1067
1068 return drm_intel_bo_alloc_userptr(bufmgr, name, addr,
1069 tiling_mode, stride, size, flags);
1070}
1071
939/** 1072/**
940 * Returns a drm_intel_bo wrapping the given buffer object handle. 1073 * Returns a drm_intel_bo wrapping the given buffer object handle.
941 * 1074 *
942 * This can be used when one application needs to pass a buffer object 1075 * This can be used when one application needs to pass a buffer object
943 * to another. 1076 * to another.
944 */ 1077 */
945drm_public drm_intel_bo * 1078drm_intel_bo *
946drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr, 1079drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
947 const char *name, 1080 const char *name,
948 unsigned int handle) 1081 unsigned int handle)
@@ -972,7 +1105,7 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
972 } 1105 }
973 } 1106 }
974 1107
975 VG_CLEAR(open_arg); 1108 memclear(open_arg);
976 open_arg.name = handle; 1109 open_arg.name = handle;
977 ret = drmIoctl(bufmgr_gem->fd, 1110 ret = drmIoctl(bufmgr_gem->fd,
978 DRM_IOCTL_GEM_OPEN, 1111 DRM_IOCTL_GEM_OPEN,
@@ -1016,8 +1149,9 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
1016 bo_gem->bo.handle = open_arg.handle; 1149 bo_gem->bo.handle = open_arg.handle;
1017 bo_gem->global_name = handle; 1150 bo_gem->global_name = handle;
1018 bo_gem->reusable = false; 1151 bo_gem->reusable = false;
1152 bo_gem->use_48b_address_range = false;
1019 1153
1020 VG_CLEAR(get_tiling); 1154 memclear(get_tiling);
1021 get_tiling.handle = bo_gem->gem_handle; 1155 get_tiling.handle = bo_gem->gem_handle;
1022 ret = drmIoctl(bufmgr_gem->fd, 1156 ret = drmIoctl(bufmgr_gem->fd,
1023 DRM_IOCTL_I915_GEM_GET_TILING, 1157 DRM_IOCTL_I915_GEM_GET_TILING,
@@ -1030,7 +1164,7 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
1030 bo_gem->tiling_mode = get_tiling.tiling_mode; 1164 bo_gem->tiling_mode = get_tiling.tiling_mode;
1031 bo_gem->swizzle_mode = get_tiling.swizzle_mode; 1165 bo_gem->swizzle_mode = get_tiling.swizzle_mode;
1032 /* XXX stride is unknown */ 1166 /* XXX stride is unknown */
1033 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem); 1167 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
1034 1168
1035 DRMINITLISTHEAD(&bo_gem->vma_list); 1169 DRMINITLISTHEAD(&bo_gem->vma_list);
1036 DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named); 1170 DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
@@ -1060,14 +1194,13 @@ drm_intel_gem_bo_free(drm_intel_bo *bo)
1060 } 1194 }
1061 1195
1062 /* Close this object */ 1196 /* Close this object */
1063 VG_CLEAR(close); 1197 memclear(close);
1064 close.handle = bo_gem->gem_handle; 1198 close.handle = bo_gem->gem_handle;
1065 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close); 1199 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
1066 if (ret != 0) { 1200 if (ret != 0) {
1067 DBG("DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n", 1201 DBG("DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n",
1068 bo_gem->gem_handle, bo_gem->name, strerror(errno)); 1202 bo_gem->gem_handle, bo_gem->name, strerror(errno));
1069 } 1203 }
1070 free(bo_gem->aub_annotations);
1071 free(bo); 1204 free(bo);
1072} 1205}
1073 1206
@@ -1192,8 +1325,12 @@ drm_intel_gem_bo_unreference_final(drm_intel_bo *bo, time_t time)
1192 time); 1325 time);
1193 } 1326 }
1194 } 1327 }
1328 for (i = 0; i < bo_gem->softpin_target_count; i++)
1329 drm_intel_gem_bo_unreference_locked_timed(bo_gem->softpin_target[i],
1330 time);
1195 bo_gem->reloc_count = 0; 1331 bo_gem->reloc_count = 0;
1196 bo_gem->used_as_reloc_target = false; 1332 bo_gem->used_as_reloc_target = false;
1333 bo_gem->softpin_target_count = 0;
1197 1334
1198 DBG("bo_unreference final: %d (%s)\n", 1335 DBG("bo_unreference final: %d (%s)\n",
1199 bo_gem->gem_handle, bo_gem->name); 1336 bo_gem->gem_handle, bo_gem->name);
@@ -1207,6 +1344,11 @@ drm_intel_gem_bo_unreference_final(drm_intel_bo *bo, time_t time)
1207 free(bo_gem->relocs); 1344 free(bo_gem->relocs);
1208 bo_gem->relocs = NULL; 1345 bo_gem->relocs = NULL;
1209 } 1346 }
1347 if (bo_gem->softpin_target) {
1348 free(bo_gem->softpin_target);
1349 bo_gem->softpin_target = NULL;
1350 bo_gem->softpin_target_size = 0;
1351 }
1210 1352
1211 /* Clear any left-over mappings */ 1353 /* Clear any left-over mappings */
1212 if (bo_gem->map_count) { 1354 if (bo_gem->map_count) {
@@ -1292,9 +1434,8 @@ static int drm_intel_gem_bo_map(drm_intel_bo *bo, int write_enable)
1292 DBG("bo_map: %d (%s), map_count=%d\n", 1434 DBG("bo_map: %d (%s), map_count=%d\n",
1293 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count); 1435 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
1294 1436
1295 VG_CLEAR(mmap_arg); 1437 memclear(mmap_arg);
1296 mmap_arg.handle = bo_gem->gem_handle; 1438 mmap_arg.handle = bo_gem->gem_handle;
1297 mmap_arg.offset = 0;
1298 mmap_arg.size = bo->size; 1439 mmap_arg.size = bo->size;
1299 ret = drmIoctl(bufmgr_gem->fd, 1440 ret = drmIoctl(bufmgr_gem->fd,
1300 DRM_IOCTL_I915_GEM_MMAP, 1441 DRM_IOCTL_I915_GEM_MMAP,
@@ -1316,7 +1457,7 @@ static int drm_intel_gem_bo_map(drm_intel_bo *bo, int write_enable)
1316 bo_gem->mem_virtual); 1457 bo_gem->mem_virtual);
1317 bo->virtual = bo_gem->mem_virtual; 1458 bo->virtual = bo_gem->mem_virtual;
1318 1459
1319 VG_CLEAR(set_domain); 1460 memclear(set_domain);
1320 set_domain.handle = bo_gem->gem_handle; 1461 set_domain.handle = bo_gem->gem_handle;
1321 set_domain.read_domains = I915_GEM_DOMAIN_CPU; 1462 set_domain.read_domains = I915_GEM_DOMAIN_CPU;
1322 if (write_enable) 1463 if (write_enable)
@@ -1362,7 +1503,7 @@ map_gtt(drm_intel_bo *bo)
1362 DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n", 1503 DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
1363 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count); 1504 bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
1364 1505
1365 VG_CLEAR(mmap_arg); 1506 memclear(mmap_arg);
1366 mmap_arg.handle = bo_gem->gem_handle; 1507 mmap_arg.handle = bo_gem->gem_handle;
1367 1508
1368 /* Get the fake offset back... */ 1509 /* Get the fake offset back... */
@@ -1405,7 +1546,7 @@ map_gtt(drm_intel_bo *bo)
1405 return 0; 1546 return 0;
1406} 1547}
1407 1548
1408drm_public int 1549int
1409drm_intel_gem_bo_map_gtt(drm_intel_bo *bo) 1550drm_intel_gem_bo_map_gtt(drm_intel_bo *bo)
1410{ 1551{
1411 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; 1552 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1430,7 +1571,7 @@ drm_intel_gem_bo_map_gtt(drm_intel_bo *bo)
1430 * tell it when we're about to use things if we had done 1571 * tell it when we're about to use things if we had done
1431 * rendering and it still happens to be bound to the GTT. 1572 * rendering and it still happens to be bound to the GTT.
1432 */ 1573 */
1433 VG_CLEAR(set_domain); 1574 memclear(set_domain);
1434 set_domain.handle = bo_gem->gem_handle; 1575 set_domain.handle = bo_gem->gem_handle;
1435 set_domain.read_domains = I915_GEM_DOMAIN_GTT; 1576 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
1436 set_domain.write_domain = I915_GEM_DOMAIN_GTT; 1577 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
@@ -1464,7 +1605,7 @@ drm_intel_gem_bo_map_gtt(drm_intel_bo *bo)
1464 * undefined). 1605 * undefined).
1465 */ 1606 */
1466 1607
1467drm_public int 1608int
1468drm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo) 1609drm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo)
1469{ 1610{
1470 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; 1611 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1529,7 +1670,7 @@ static int drm_intel_gem_bo_unmap(drm_intel_bo *bo)
1529 * Unlike GTT set domains, this only does work if the 1670 * Unlike GTT set domains, this only does work if the
1530 * buffer should be scanout-related. 1671 * buffer should be scanout-related.
1531 */ 1672 */
1532 VG_CLEAR(sw_finish); 1673 memclear(sw_finish);
1533 sw_finish.handle = bo_gem->gem_handle; 1674 sw_finish.handle = bo_gem->gem_handle;
1534 ret = drmIoctl(bufmgr_gem->fd, 1675 ret = drmIoctl(bufmgr_gem->fd,
1535 DRM_IOCTL_I915_GEM_SW_FINISH, 1676 DRM_IOCTL_I915_GEM_SW_FINISH,
@@ -1553,7 +1694,7 @@ static int drm_intel_gem_bo_unmap(drm_intel_bo *bo)
1553 return ret; 1694 return ret;
1554} 1695}
1555 1696
1556drm_public int 1697int
1557drm_intel_gem_bo_unmap_gtt(drm_intel_bo *bo) 1698drm_intel_gem_bo_unmap_gtt(drm_intel_bo *bo)
1558{ 1699{
1559 return drm_intel_gem_bo_unmap(bo); 1700 return drm_intel_gem_bo_unmap(bo);
@@ -1571,7 +1712,7 @@ drm_intel_gem_bo_subdata(drm_intel_bo *bo, unsigned long offset,
1571 if (bo_gem->is_userptr) 1712 if (bo_gem->is_userptr)
1572 return -EINVAL; 1713 return -EINVAL;
1573 1714
1574 VG_CLEAR(pwrite); 1715 memclear(pwrite);
1575 pwrite.handle = bo_gem->gem_handle; 1716 pwrite.handle = bo_gem->gem_handle;
1576 pwrite.offset = offset; 1717 pwrite.offset = offset;
1577 pwrite.size = size; 1718 pwrite.size = size;
@@ -1596,7 +1737,7 @@ drm_intel_gem_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id)
1596 struct drm_i915_get_pipe_from_crtc_id get_pipe_from_crtc_id; 1737 struct drm_i915_get_pipe_from_crtc_id get_pipe_from_crtc_id;
1597 int ret; 1738 int ret;
1598 1739
1599 VG_CLEAR(get_pipe_from_crtc_id); 1740 memclear(get_pipe_from_crtc_id);
1600 get_pipe_from_crtc_id.crtc_id = crtc_id; 1741 get_pipe_from_crtc_id.crtc_id = crtc_id;
1601 ret = drmIoctl(bufmgr_gem->fd, 1742 ret = drmIoctl(bufmgr_gem->fd,
1602 DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID, 1743 DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
@@ -1626,7 +1767,7 @@ drm_intel_gem_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
1626 if (bo_gem->is_userptr) 1767 if (bo_gem->is_userptr)
1627 return -EINVAL; 1768 return -EINVAL;
1628 1769
1629 VG_CLEAR(pread); 1770 memclear(pread);
1630 pread.handle = bo_gem->gem_handle; 1771 pread.handle = bo_gem->gem_handle;
1631 pread.offset = offset; 1772 pread.offset = offset;
1632 pread.size = size; 1773 pread.size = size;
@@ -1674,8 +1815,11 @@ drm_intel_gem_bo_wait_rendering(drm_intel_bo *bo)
1674 * not guarantee that the buffer is re-issued via another thread, or an flinked 1815 * not guarantee that the buffer is re-issued via another thread, or an flinked
1675 * handle. Userspace must make sure this race does not occur if such precision 1816 * handle. Userspace must make sure this race does not occur if such precision
1676 * is important. 1817 * is important.
1818 *
1819 * Note that some kernels have broken the inifite wait for negative values
1820 * promise, upgrade to latest stable kernels if this is the case.
1677 */ 1821 */
1678drm_public int 1822int
1679drm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns) 1823drm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns)
1680{ 1824{
1681 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; 1825 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1694,9 +1838,9 @@ drm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns)
1694 } 1838 }
1695 } 1839 }
1696 1840
1841 memclear(wait);
1697 wait.bo_handle = bo_gem->gem_handle; 1842 wait.bo_handle = bo_gem->gem_handle;
1698 wait.timeout_ns = timeout_ns; 1843 wait.timeout_ns = timeout_ns;
1699 wait.flags = 0;
1700 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_WAIT, &wait); 1844 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_WAIT, &wait);
1701 if (ret == -1) 1845 if (ret == -1)
1702 return -errno; 1846 return -errno;
@@ -1711,7 +1855,7 @@ drm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns)
1711 * In combination with drm_intel_gem_bo_pin() and manual fence management, we 1855 * In combination with drm_intel_gem_bo_pin() and manual fence management, we
1712 * can do tiled pixmaps this way. 1856 * can do tiled pixmaps this way.
1713 */ 1857 */
1714drm_public void 1858void
1715drm_intel_gem_bo_start_gtt_access(drm_intel_bo *bo, int write_enable) 1859drm_intel_gem_bo_start_gtt_access(drm_intel_bo *bo, int write_enable)
1716{ 1860{
1717 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; 1861 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1719,7 +1863,7 @@ drm_intel_gem_bo_start_gtt_access(drm_intel_bo *bo, int write_enable)
1719 struct drm_i915_gem_set_domain set_domain; 1863 struct drm_i915_gem_set_domain set_domain;
1720 int ret; 1864 int ret;
1721 1865
1722 VG_CLEAR(set_domain); 1866 memclear(set_domain);
1723 set_domain.handle = bo_gem->gem_handle; 1867 set_domain.handle = bo_gem->gem_handle;
1724 set_domain.read_domains = I915_GEM_DOMAIN_GTT; 1868 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
1725 set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_GTT : 0; 1869 set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_GTT : 0;
@@ -1738,12 +1882,12 @@ static void
1738drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr) 1882drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr)
1739{ 1883{
1740 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr; 1884 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
1741 int i; 1885 struct drm_gem_close close_bo;
1886 int i, ret;
1742 1887
1743 free(bufmgr_gem->exec2_objects); 1888 free(bufmgr_gem->exec2_objects);
1744 free(bufmgr_gem->exec_objects); 1889 free(bufmgr_gem->exec_objects);
1745 free(bufmgr_gem->exec_bos); 1890 free(bufmgr_gem->exec_bos);
1746 free(bufmgr_gem->aub_filename);
1747 1891
1748 pthread_mutex_destroy(&bufmgr_gem->lock); 1892 pthread_mutex_destroy(&bufmgr_gem->lock);
1749 1893
@@ -1762,6 +1906,18 @@ drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr)
1762 } 1906 }
1763 } 1907 }
1764 1908
1909 /* Release userptr bo kept hanging around for optimisation. */
1910 if (bufmgr_gem->userptr_active.ptr) {
1911 memclear(close_bo);
1912 close_bo.handle = bufmgr_gem->userptr_active.handle;
1913 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
1914 free(bufmgr_gem->userptr_active.ptr);
1915 if (ret)
1916 fprintf(stderr,
1917 "Failed to release test userptr object! (%d) "
1918 "i915 kernel driver may not be sane!\n", errno);
1919 }
1920
1765 free(bufmgr); 1921 free(bufmgr);
1766} 1922}
1767 1923
@@ -1830,14 +1986,6 @@ do_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
1830 bo_gem->reloc_tree_fences += target_bo_gem->reloc_tree_fences; 1986 bo_gem->reloc_tree_fences += target_bo_gem->reloc_tree_fences;
1831 } 1987 }
1832 1988
1833 bo_gem->relocs[bo_gem->reloc_count].offset = offset;
1834 bo_gem->relocs[bo_gem->reloc_count].delta = target_offset;
1835 bo_gem->relocs[bo_gem->reloc_count].target_handle =
1836 target_bo_gem->gem_handle;
1837 bo_gem->relocs[bo_gem->reloc_count].read_domains = read_domains;
1838 bo_gem->relocs[bo_gem->reloc_count].write_domain = write_domain;
1839 bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset64;
1840
1841 bo_gem->reloc_target_info[bo_gem->reloc_count].bo = target_bo; 1989 bo_gem->reloc_target_info[bo_gem->reloc_count].bo = target_bo;
1842 if (target_bo != bo) 1990 if (target_bo != bo)
1843 drm_intel_gem_bo_reference(target_bo); 1991 drm_intel_gem_bo_reference(target_bo);
@@ -1847,21 +1995,77 @@ do_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
1847 else 1995 else
1848 bo_gem->reloc_target_info[bo_gem->reloc_count].flags = 0; 1996 bo_gem->reloc_target_info[bo_gem->reloc_count].flags = 0;
1849 1997
1998 bo_gem->relocs[bo_gem->reloc_count].offset = offset;
1999 bo_gem->relocs[bo_gem->reloc_count].delta = target_offset;
2000 bo_gem->relocs[bo_gem->reloc_count].target_handle =
2001 target_bo_gem->gem_handle;
2002 bo_gem->relocs[bo_gem->reloc_count].read_domains = read_domains;
2003 bo_gem->relocs[bo_gem->reloc_count].write_domain = write_domain;
2004 bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset64;
1850 bo_gem->reloc_count++; 2005 bo_gem->reloc_count++;
1851 2006
1852 return 0; 2007 return 0;
1853} 2008}
1854 2009
2010static void
2011drm_intel_gem_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
2012{
2013 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2014 bo_gem->use_48b_address_range = enable;
2015}
2016
2017static int
2018drm_intel_gem_bo_add_softpin_target(drm_intel_bo *bo, drm_intel_bo *target_bo)
2019{
2020 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
2021 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2022 drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) target_bo;
2023 if (bo_gem->has_error)
2024 return -ENOMEM;
2025
2026 if (target_bo_gem->has_error) {
2027 bo_gem->has_error = true;
2028 return -ENOMEM;
2029 }
2030
2031 if (!target_bo_gem->is_softpin)
2032 return -EINVAL;
2033 if (target_bo_gem == bo_gem)
2034 return -EINVAL;
2035
2036 if (bo_gem->softpin_target_count == bo_gem->softpin_target_size) {
2037 int new_size = bo_gem->softpin_target_size * 2;
2038 if (new_size == 0)
2039 new_size = bufmgr_gem->max_relocs;
2040
2041 bo_gem->softpin_target = realloc(bo_gem->softpin_target, new_size *
2042 sizeof(drm_intel_bo *));
2043 if (!bo_gem->softpin_target)
2044 return -ENOMEM;
2045
2046 bo_gem->softpin_target_size = new_size;
2047 }
2048 bo_gem->softpin_target[bo_gem->softpin_target_count] = target_bo;
2049 drm_intel_gem_bo_reference(target_bo);
2050 bo_gem->softpin_target_count++;
2051
2052 return 0;
2053}
2054
1855static int 2055static int
1856drm_intel_gem_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset, 2056drm_intel_gem_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
1857 drm_intel_bo *target_bo, uint32_t target_offset, 2057 drm_intel_bo *target_bo, uint32_t target_offset,
1858 uint32_t read_domains, uint32_t write_domain) 2058 uint32_t read_domains, uint32_t write_domain)
1859{ 2059{
1860 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr; 2060 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
2061 drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *)target_bo;
1861 2062
1862 return do_bo_emit_reloc(bo, offset, target_bo, target_offset, 2063 if (target_bo_gem->is_softpin)
1863 read_domains, write_domain, 2064 return drm_intel_gem_bo_add_softpin_target(bo, target_bo);
1864 !bufmgr_gem->fenced_relocs); 2065 else
2066 return do_bo_emit_reloc(bo, offset, target_bo, target_offset,
2067 read_domains, write_domain,
2068 !bufmgr_gem->fenced_relocs);
1865} 2069}
1866 2070
1867static int 2071static int
@@ -1874,7 +2078,7 @@ drm_intel_gem_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
1874 read_domains, write_domain, true); 2078 read_domains, write_domain, true);
1875} 2079}
1876 2080
1877drm_public int 2081int
1878drm_intel_gem_bo_get_reloc_count(drm_intel_bo *bo) 2082drm_intel_gem_bo_get_reloc_count(drm_intel_bo *bo)
1879{ 2083{
1880 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; 2084 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -1894,8 +2098,10 @@ drm_intel_gem_bo_get_reloc_count(drm_intel_bo *bo)
1894 * 2098 *
1895 * Any further drm_intel_bufmgr_check_aperture_space() queries 2099 * Any further drm_intel_bufmgr_check_aperture_space() queries
1896 * involving this buffer in the tree are undefined after this call. 2100 * involving this buffer in the tree are undefined after this call.
2101 *
2102 * This also removes all softpinned targets being referenced by the BO.
1897 */ 2103 */
1898drm_public void 2104void
1899drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start) 2105drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start)
1900{ 2106{
1901 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; 2107 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1920,6 +2126,12 @@ drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start)
1920 } 2126 }
1921 bo_gem->reloc_count = start; 2127 bo_gem->reloc_count = start;
1922 2128
2129 for (i = 0; i < bo_gem->softpin_target_count; i++) {
2130 drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) bo_gem->softpin_target[i];
2131 drm_intel_gem_bo_unreference_locked_timed(&target_bo_gem->bo, time.tv_sec);
2132 }
2133 bo_gem->softpin_target_count = 0;
2134
1923 pthread_mutex_unlock(&bufmgr_gem->lock); 2135 pthread_mutex_unlock(&bufmgr_gem->lock);
1924 2136
1925} 2137}
@@ -1960,7 +2172,7 @@ drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
1960 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo; 2172 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
1961 int i; 2173 int i;
1962 2174
1963 if (bo_gem->relocs == NULL) 2175 if (bo_gem->relocs == NULL && bo_gem->softpin_target == NULL)
1964 return; 2176 return;
1965 2177
1966 for (i = 0; i < bo_gem->reloc_count; i++) { 2178 for (i = 0; i < bo_gem->reloc_count; i++) {
@@ -1981,6 +2193,17 @@ drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
1981 /* Add the target to the validate list */ 2193 /* Add the target to the validate list */
1982 drm_intel_add_validate_buffer2(target_bo, need_fence); 2194 drm_intel_add_validate_buffer2(target_bo, need_fence);
1983 } 2195 }
2196
2197 for (i = 0; i < bo_gem->softpin_target_count; i++) {
2198 drm_intel_bo *target_bo = bo_gem->softpin_target[i];
2199
2200 if (target_bo == bo)
2201 continue;
2202
2203 drm_intel_gem_bo_mark_mmaps_incoherent(bo);
2204 drm_intel_gem_bo_process_reloc2(target_bo);
2205 drm_intel_add_validate_buffer2(target_bo, false);
2206 }
1984} 2207}
1985 2208
1986 2209
@@ -1995,10 +2218,12 @@ drm_intel_update_buffer_offsets(drm_intel_bufmgr_gem *bufmgr_gem)
1995 2218
1996 /* Update the buffer offset */ 2219 /* Update the buffer offset */
1997 if (bufmgr_gem->exec_objects[i].offset != bo->offset64) { 2220 if (bufmgr_gem->exec_objects[i].offset != bo->offset64) {
1998 DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n", 2221 DBG("BO %d (%s) migrated: 0x%08x %08x -> 0x%08x %08x\n",
1999 bo_gem->gem_handle, bo_gem->name, bo->offset64, 2222 bo_gem->gem_handle, bo_gem->name,
2000 (unsigned long long)bufmgr_gem->exec_objects[i]. 2223 upper_32_bits(bo->offset64),
2001 offset); 2224 lower_32_bits(bo->offset64),
2225 upper_32_bits(bufmgr_gem->exec_objects[i].offset),
2226 lower_32_bits(bufmgr_gem->exec_objects[i].offset));
2002 bo->offset64 = bufmgr_gem->exec_objects[i].offset; 2227 bo->offset64 = bufmgr_gem->exec_objects[i].offset;
2003 bo->offset = bufmgr_gem->exec_objects[i].offset; 2228 bo->offset = bufmgr_gem->exec_objects[i].offset;
2004 } 2229 }
@@ -2016,306 +2241,28 @@ drm_intel_update_buffer_offsets2 (drm_intel_bufmgr_gem *bufmgr_gem)
2016 2241
2017 /* Update the buffer offset */ 2242 /* Update the buffer offset */
2018 if (bufmgr_gem->exec2_objects[i].offset != bo->offset64) { 2243 if (bufmgr_gem->exec2_objects[i].offset != bo->offset64) {
2019 DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n", 2244 /* If we're seeing softpinned object here it means that the kernel
2020 bo_gem->gem_handle, bo_gem->name, bo->offset64, 2245 * has relocated our object... Indicating a programming error
2021 (unsigned long long)bufmgr_gem->exec2_objects[i].offset); 2246 */
2247 assert(!bo_gem->is_softpin);
2248 DBG("BO %d (%s) migrated: 0x%08x %08x -> 0x%08x %08x\n",
2249 bo_gem->gem_handle, bo_gem->name,
2250 upper_32_bits(bo->offset64),
2251 lower_32_bits(bo->offset64),
2252 upper_32_bits(bufmgr_gem->exec2_objects[i].offset),
2253 lower_32_bits(bufmgr_gem->exec2_objects[i].offset));
2022 bo->offset64 = bufmgr_gem->exec2_objects[i].offset; 2254 bo->offset64 = bufmgr_gem->exec2_objects[i].offset;
2023 bo->offset = bufmgr_gem->exec2_objects[i].offset; 2255 bo->offset = bufmgr_gem->exec2_objects[i].offset;
2024 } 2256 }
2025 } 2257 }
2026} 2258}
2027 2259
2028static void 2260void
2029aub_out(drm_intel_bufmgr_gem *bufmgr_gem, uint32_t data)
2030{
2031 fwrite(&data, 1, 4, bufmgr_gem->aub_file);
2032}
2033
2034static void
2035aub_out_data(drm_intel_bufmgr_gem *bufmgr_gem, void *data, size_t size)
2036{
2037 fwrite(data, 1, size, bufmgr_gem->aub_file);
2038}
2039
2040static void
2041aub_write_bo_data(drm_intel_bo *bo, uint32_t offset, uint32_t size)
2042{
2043 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
2044 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2045 uint32_t *data;
2046 unsigned int i;
2047
2048 data = malloc(bo->size);
2049 drm_intel_bo_get_subdata(bo, offset, size, data);
2050
2051 /* Easy mode: write out bo with no relocations */
2052 if (!bo_gem->reloc_count) {
2053 aub_out_data(bufmgr_gem, data, size);
2054 free(data);
2055 return;
2056 }
2057
2058 /* Otherwise, handle the relocations while writing. */
2059 for (i = 0; i < size / 4; i++) {
2060 int r;
2061 for (r = 0; r < bo_gem->reloc_count; r++) {
2062 struct drm_i915_gem_relocation_entry *reloc;
2063 drm_intel_reloc_target *info;
2064
2065 reloc = &bo_gem->relocs[r];
2066 info = &bo_gem->reloc_target_info[r];
2067
2068 if (reloc->offset == offset + i * 4) {
2069 drm_intel_bo_gem *target_gem;
2070 uint32_t val;
2071
2072 target_gem = (drm_intel_bo_gem *)info->bo;
2073
2074 val = reloc->delta;
2075 val += target_gem->aub_offset;
2076
2077 aub_out(bufmgr_gem, val);
2078 data[i] = val;
2079 break;
2080 }
2081 }
2082 if (r == bo_gem->reloc_count) {
2083 /* no relocation, just the data */
2084 aub_out(bufmgr_gem, data[i]);
2085 }
2086 }
2087
2088 free(data);
2089}
2090
2091static void
2092aub_bo_get_address(drm_intel_bo *bo)
2093{
2094 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
2095 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2096
2097 /* Give the object a graphics address in the AUB file. We
2098 * don't just use the GEM object address because we do AUB
2099 * dumping before execution -- we want to successfully log
2100 * when the hardware might hang, and we might even want to aub
2101 * capture for a driver trying to execute on a different
2102 * generation of hardware by disabling the actual kernel exec
2103 * call.
2104 */
2105 bo_gem->aub_offset = bufmgr_gem->aub_offset;
2106 bufmgr_gem->aub_offset += bo->size;
2107 /* XXX: Handle aperture overflow. */
2108 assert(bufmgr_gem->aub_offset < 256 * 1024 * 1024);
2109}
2110
2111static void
2112aub_write_trace_block(drm_intel_bo *bo, uint32_t type, uint32_t subtype,
2113 uint32_t offset, uint32_t size)
2114{
2115 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
2116 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2117
2118 aub_out(bufmgr_gem,
2119 CMD_AUB_TRACE_HEADER_BLOCK |
2120 ((bufmgr_gem->gen >= 8 ? 6 : 5) - 2));
2121 aub_out(bufmgr_gem,
2122 AUB_TRACE_MEMTYPE_GTT | type | AUB_TRACE_OP_DATA_WRITE);
2123 aub_out(bufmgr_gem, subtype);
2124 aub_out(bufmgr_gem, bo_gem->aub_offset + offset);
2125 aub_out(bufmgr_gem, size);
2126 if (bufmgr_gem->gen >= 8)
2127 aub_out(bufmgr_gem, 0);
2128 aub_write_bo_data(bo, offset, size);
2129}
2130
2131/**
2132 * Break up large objects into multiple writes. Otherwise a 128kb VBO
2133 * would overflow the 16 bits of size field in the packet header and
2134 * everything goes badly after that.
2135 */
2136static void
2137aub_write_large_trace_block(drm_intel_bo *bo, uint32_t type, uint32_t subtype,
2138 uint32_t offset, uint32_t size)
2139{
2140 uint32_t block_size;
2141 uint32_t sub_offset;
2142
2143 for (sub_offset = 0; sub_offset < size; sub_offset += block_size) {
2144 block_size = size - sub_offset;
2145
2146 if (block_size > 8 * 4096)
2147 block_size = 8 * 4096;
2148
2149 aub_write_trace_block(bo, type, subtype, offset + sub_offset,
2150 block_size);
2151 }
2152}
2153
2154static void
2155aub_write_bo(drm_intel_bo *bo)
2156{
2157 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2158 uint32_t offset = 0;
2159 unsigned i;
2160
2161 aub_bo_get_address(bo);
2162
2163 /* Write out each annotated section separately. */
2164 for (i = 0; i < bo_gem->aub_annotation_count; ++i) {
2165 drm_intel_aub_annotation *annotation =
2166 &bo_gem->aub_annotations[i];
2167 uint32_t ending_offset = annotation->ending_offset;
2168 if (ending_offset > bo->size)
2169 ending_offset = bo->size;
2170 if (ending_offset > offset) {
2171 aub_write_large_trace_block(bo, annotation->type,
2172 annotation->subtype,
2173 offset,
2174 ending_offset - offset);
2175 offset = ending_offset;
2176 }
2177 }
2178
2179 /* Write out any remaining unannotated data */
2180 if (offset < bo->size) {
2181 aub_write_large_trace_block(bo, AUB_TRACE_TYPE_NOTYPE, 0,
2182 offset, bo->size - offset);
2183 }
2184}
2185
2186/*
2187 * Make a ringbuffer on fly and dump it
2188 */
2189static void
2190aub_build_dump_ringbuffer(drm_intel_bufmgr_gem *bufmgr_gem,
2191 uint32_t batch_buffer, int ring_flag)
2192{
2193 uint32_t ringbuffer[4096];
2194 int ring = AUB_TRACE_TYPE_RING_PRB0; /* The default ring */
2195 int ring_count = 0;
2196
2197 if (ring_flag == I915_EXEC_BSD)
2198 ring = AUB_TRACE_TYPE_RING_PRB1;
2199 else if (ring_flag == I915_EXEC_BLT)
2200 ring = AUB_TRACE_TYPE_RING_PRB2;
2201
2202 /* Make a ring buffer to execute our batchbuffer. */
2203 memset(ringbuffer, 0, sizeof(ringbuffer));
2204 if (bufmgr_gem->gen >= 8) {
2205 ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START | (3 - 2);
2206 ringbuffer[ring_count++] = batch_buffer;
2207 ringbuffer[ring_count++] = 0;
2208 } else {
2209 ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START;
2210 ringbuffer[ring_count++] = batch_buffer;
2211 }
2212
2213 /* Write out the ring. This appears to trigger execution of
2214 * the ring in the simulator.
2215 */
2216 aub_out(bufmgr_gem,
2217 CMD_AUB_TRACE_HEADER_BLOCK |
2218 ((bufmgr_gem->gen >= 8 ? 6 : 5) - 2));
2219 aub_out(bufmgr_gem,
2220 AUB_TRACE_MEMTYPE_GTT | ring | AUB_TRACE_OP_COMMAND_WRITE);
2221 aub_out(bufmgr_gem, 0); /* general/surface subtype */
2222 aub_out(bufmgr_gem, bufmgr_gem->aub_offset);
2223 aub_out(bufmgr_gem, ring_count * 4);
2224 if (bufmgr_gem->gen >= 8)
2225 aub_out(bufmgr_gem, 0);
2226
2227 /* FIXME: Need some flush operations here? */
2228 aub_out_data(bufmgr_gem, ringbuffer, ring_count * 4);
2229
2230 /* Update offset pointer */
2231 bufmgr_gem->aub_offset += 4096;
2232}
2233
2234drm_public void
2235drm_intel_gem_bo_aub_dump_bmp(drm_intel_bo *bo, 2261drm_intel_gem_bo_aub_dump_bmp(drm_intel_bo *bo,
2236 int x1, int y1, int width, int height, 2262 int x1, int y1, int width, int height,
2237 enum aub_dump_bmp_format format, 2263 enum aub_dump_bmp_format format,
2238 int pitch, int offset) 2264 int pitch, int offset)
2239{ 2265{
2240 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
2241 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
2242 uint32_t cpp;
2243
2244 switch (format) {
2245 case AUB_DUMP_BMP_FORMAT_8BIT:
2246 cpp = 1;
2247 break;
2248 case AUB_DUMP_BMP_FORMAT_ARGB_4444:
2249 cpp = 2;
2250 break;
2251 case AUB_DUMP_BMP_FORMAT_ARGB_0888:
2252 case AUB_DUMP_BMP_FORMAT_ARGB_8888:
2253 cpp = 4;
2254 break;
2255 default:
2256 printf("Unknown AUB dump format %d\n", format);
2257 return;
2258 }
2259
2260 if (!bufmgr_gem->aub_file)
2261 return;
2262
2263 aub_out(bufmgr_gem, CMD_AUB_DUMP_BMP | 4);
2264 aub_out(bufmgr_gem, (y1 << 16) | x1);
2265 aub_out(bufmgr_gem,
2266 (format << 24) |
2267 (cpp << 19) |
2268 pitch / 4);
2269 aub_out(bufmgr_gem, (height << 16) | width);
2270 aub_out(bufmgr_gem, bo_gem->aub_offset + offset);
2271 aub_out(bufmgr_gem,
2272 ((bo_gem->tiling_mode != I915_TILING_NONE) ? (1 << 2) : 0) |
2273 ((bo_gem->tiling_mode == I915_TILING_Y) ? (1 << 3) : 0));
2274}
2275
2276static void
2277aub_exec(drm_intel_bo *bo, int ring_flag, int used)
2278{
2279 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
2280 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2281 int i;
2282 bool batch_buffer_needs_annotations;
2283
2284 if (!bufmgr_gem->aub_file)
2285 return;
2286
2287 /* If batch buffer is not annotated, annotate it the best we
2288 * can.
2289 */
2290 batch_buffer_needs_annotations = bo_gem->aub_annotation_count == 0;
2291 if (batch_buffer_needs_annotations) {
2292 drm_intel_aub_annotation annotations[2] = {
2293 { AUB_TRACE_TYPE_BATCH, 0, used },
2294 { AUB_TRACE_TYPE_NOTYPE, 0, bo->size }
2295 };
2296 drm_intel_bufmgr_gem_set_aub_annotations(bo, annotations, 2);
2297 }
2298
2299 /* Write out all buffers to AUB memory */
2300 for (i = 0; i < bufmgr_gem->exec_count; i++) {
2301 aub_write_bo(bufmgr_gem->exec_bos[i]);
2302 }
2303
2304 /* Remove any annotations we added */
2305 if (batch_buffer_needs_annotations)
2306 drm_intel_bufmgr_gem_set_aub_annotations(bo, NULL, 0);
2307
2308 /* Dump ring buffer */
2309 aub_build_dump_ringbuffer(bufmgr_gem, bo_gem->aub_offset, ring_flag);
2310
2311 fflush(bufmgr_gem->aub_file);
2312
2313 /*
2314 * One frame has been dumped. So reset the aub_offset for the next frame.
2315 *
2316 * FIXME: Can we do this?
2317 */
2318 bufmgr_gem->aub_offset = 0x10000;
2319} 2266}
2320 2267
2321static int 2268static int
@@ -2323,11 +2270,10 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
2323 drm_clip_rect_t * cliprects, int num_cliprects, int DR4) 2270 drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
2324{ 2271{
2325 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; 2272 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
2326 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2327 struct drm_i915_gem_execbuffer execbuf; 2273 struct drm_i915_gem_execbuffer execbuf;
2328 int ret, i; 2274 int ret, i;
2329 2275
2330 if (bo_gem->has_error) 2276 if (to_bo_gem(bo)->has_error)
2331 return -ENOMEM; 2277 return -ENOMEM;
2332 2278
2333 pthread_mutex_lock(&bufmgr_gem->lock); 2279 pthread_mutex_lock(&bufmgr_gem->lock);
@@ -2339,7 +2285,7 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
2339 */ 2285 */
2340 drm_intel_add_validate_buffer(bo); 2286 drm_intel_add_validate_buffer(bo);
2341 2287
2342 VG_CLEAR(execbuf); 2288 memclear(execbuf);
2343 execbuf.buffers_ptr = (uintptr_t) bufmgr_gem->exec_objects; 2289 execbuf.buffers_ptr = (uintptr_t) bufmgr_gem->exec_objects;
2344 execbuf.buffer_count = bufmgr_gem->exec_count; 2290 execbuf.buffer_count = bufmgr_gem->exec_count;
2345 execbuf.batch_start_offset = 0; 2291 execbuf.batch_start_offset = 0;
@@ -2372,8 +2318,7 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
2372 drm_intel_gem_dump_validation_list(bufmgr_gem); 2318 drm_intel_gem_dump_validation_list(bufmgr_gem);
2373 2319
2374 for (i = 0; i < bufmgr_gem->exec_count; i++) { 2320 for (i = 0; i < bufmgr_gem->exec_count; i++) {
2375 drm_intel_bo *bo = bufmgr_gem->exec_bos[i]; 2321 drm_intel_bo_gem *bo_gem = to_bo_gem(bufmgr_gem->exec_bos[i]);
2376 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2377 2322
2378 bo_gem->idle = false; 2323 bo_gem->idle = false;
2379 2324
@@ -2397,6 +2342,9 @@ do_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx,
2397 int ret = 0; 2342 int ret = 0;
2398 int i; 2343 int i;
2399 2344
2345 if (to_bo_gem(bo)->has_error)
2346 return -ENOMEM;
2347
2400 switch (flags & 0x7) { 2348 switch (flags & 0x7) {
2401 default: 2349 default:
2402 return -EINVAL; 2350 return -EINVAL;
@@ -2426,7 +2374,7 @@ do_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx,
2426 */ 2374 */
2427 drm_intel_add_validate_buffer2(bo, 0); 2375 drm_intel_add_validate_buffer2(bo, 0);
2428 2376
2429 VG_CLEAR(execbuf); 2377 memclear(execbuf);
2430 execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects; 2378 execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects;
2431 execbuf.buffer_count = bufmgr_gem->exec_count; 2379 execbuf.buffer_count = bufmgr_gem->exec_count;
2432 execbuf.batch_start_offset = 0; 2380 execbuf.batch_start_offset = 0;
@@ -2442,8 +2390,6 @@ do_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx,
2442 i915_execbuffer2_set_context_id(execbuf, ctx->ctx_id); 2390 i915_execbuffer2_set_context_id(execbuf, ctx->ctx_id);
2443 execbuf.rsvd2 = 0; 2391 execbuf.rsvd2 = 0;
2444 2392
2445 aub_exec(bo, flags, used);
2446
2447 if (bufmgr_gem->no_exec) 2393 if (bufmgr_gem->no_exec)
2448 goto skip_execution; 2394 goto skip_execution;
2449 2395
@@ -2469,8 +2415,7 @@ skip_execution:
2469 drm_intel_gem_dump_validation_list(bufmgr_gem); 2415 drm_intel_gem_dump_validation_list(bufmgr_gem);
2470 2416
2471 for (i = 0; i < bufmgr_gem->exec_count; i++) { 2417 for (i = 0; i < bufmgr_gem->exec_count; i++) {
2472 drm_intel_bo *bo = bufmgr_gem->exec_bos[i]; 2418 drm_intel_bo_gem *bo_gem = to_bo_gem(bufmgr_gem->exec_bos[i]);
2473 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
2474 2419
2475 bo_gem->idle = false; 2420 bo_gem->idle = false;
2476 2421
@@ -2502,7 +2447,7 @@ drm_intel_gem_bo_mrb_exec2(drm_intel_bo *bo, int used,
2502 flags); 2447 flags);
2503} 2448}
2504 2449
2505drm_public int 2450int
2506drm_intel_gem_bo_context_exec(drm_intel_bo *bo, drm_intel_context *ctx, 2451drm_intel_gem_bo_context_exec(drm_intel_bo *bo, drm_intel_context *ctx,
2507 int used, unsigned int flags) 2452 int used, unsigned int flags)
2508{ 2453{
@@ -2517,7 +2462,7 @@ drm_intel_gem_bo_pin(drm_intel_bo *bo, uint32_t alignment)
2517 struct drm_i915_gem_pin pin; 2462 struct drm_i915_gem_pin pin;
2518 int ret; 2463 int ret;
2519 2464
2520 VG_CLEAR(pin); 2465 memclear(pin);
2521 pin.handle = bo_gem->gem_handle; 2466 pin.handle = bo_gem->gem_handle;
2522 pin.alignment = alignment; 2467 pin.alignment = alignment;
2523 2468
@@ -2540,7 +2485,7 @@ drm_intel_gem_bo_unpin(drm_intel_bo *bo)
2540 struct drm_i915_gem_unpin unpin; 2485 struct drm_i915_gem_unpin unpin;
2541 int ret; 2486 int ret;
2542 2487
2543 VG_CLEAR(unpin); 2488 memclear(unpin);
2544 unpin.handle = bo_gem->gem_handle; 2489 unpin.handle = bo_gem->gem_handle;
2545 2490
2546 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin); 2491 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin);
@@ -2610,7 +2555,7 @@ drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
2610 2555
2611 ret = drm_intel_gem_bo_set_tiling_internal(bo, *tiling_mode, stride); 2556 ret = drm_intel_gem_bo_set_tiling_internal(bo, *tiling_mode, stride);
2612 if (ret == 0) 2557 if (ret == 0)
2613 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem); 2558 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
2614 2559
2615 *tiling_mode = bo_gem->tiling_mode; 2560 *tiling_mode = bo_gem->tiling_mode;
2616 return ret; 2561 return ret;
@@ -2627,7 +2572,18 @@ drm_intel_gem_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
2627 return 0; 2572 return 0;
2628} 2573}
2629 2574
2630drm_public drm_intel_bo * 2575static int
2576drm_intel_gem_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset)
2577{
2578 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2579
2580 bo_gem->is_softpin = true;
2581 bo->offset64 = offset;
2582 bo->offset = offset;
2583 return 0;
2584}
2585
2586drm_intel_bo *
2631drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int size) 2587drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int size)
2632{ 2588{
2633 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr; 2589 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
@@ -2637,14 +2593,19 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
2637 struct drm_i915_gem_get_tiling get_tiling; 2593 struct drm_i915_gem_get_tiling get_tiling;
2638 drmMMListHead *list; 2594 drmMMListHead *list;
2639 2595
2596 pthread_mutex_lock(&bufmgr_gem->lock);
2640 ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle); 2597 ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle);
2598 if (ret) {
2599 DBG("create_from_prime: failed to obtain handle from fd: %s\n", strerror(errno));
2600 pthread_mutex_unlock(&bufmgr_gem->lock);
2601 return NULL;
2602 }
2641 2603
2642 /* 2604 /*
2643 * See if the kernel has already returned this buffer to us. Just as 2605 * See if the kernel has already returned this buffer to us. Just as
2644 * for named buffers, we must not create two bo's pointing at the same 2606 * for named buffers, we must not create two bo's pointing at the same
2645 * kernel object 2607 * kernel object
2646 */ 2608 */
2647 pthread_mutex_lock(&bufmgr_gem->lock);
2648 for (list = bufmgr_gem->named.next; 2609 for (list = bufmgr_gem->named.next;
2649 list != &bufmgr_gem->named; 2610 list != &bufmgr_gem->named;
2650 list = list->next) { 2611 list = list->next) {
@@ -2656,12 +2617,6 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
2656 } 2617 }
2657 } 2618 }
2658 2619
2659 if (ret) {
2660 fprintf(stderr,"ret is %d %d\n", ret, errno);
2661 pthread_mutex_unlock(&bufmgr_gem->lock);
2662 return NULL;
2663 }
2664
2665 bo_gem = calloc(1, sizeof(*bo_gem)); 2620 bo_gem = calloc(1, sizeof(*bo_gem));
2666 if (!bo_gem) { 2621 if (!bo_gem) {
2667 pthread_mutex_unlock(&bufmgr_gem->lock); 2622 pthread_mutex_unlock(&bufmgr_gem->lock);
@@ -2691,29 +2646,31 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
2691 bo_gem->used_as_reloc_target = false; 2646 bo_gem->used_as_reloc_target = false;
2692 bo_gem->has_error = false; 2647 bo_gem->has_error = false;
2693 bo_gem->reusable = false; 2648 bo_gem->reusable = false;
2649 bo_gem->use_48b_address_range = false;
2694 2650
2695 DRMINITLISTHEAD(&bo_gem->vma_list); 2651 DRMINITLISTHEAD(&bo_gem->vma_list);
2696 DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named); 2652 DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
2697 pthread_mutex_unlock(&bufmgr_gem->lock); 2653 pthread_mutex_unlock(&bufmgr_gem->lock);
2698 2654
2699 VG_CLEAR(get_tiling); 2655 memclear(get_tiling);
2700 get_tiling.handle = bo_gem->gem_handle; 2656 get_tiling.handle = bo_gem->gem_handle;
2701 ret = drmIoctl(bufmgr_gem->fd, 2657 ret = drmIoctl(bufmgr_gem->fd,
2702 DRM_IOCTL_I915_GEM_GET_TILING, 2658 DRM_IOCTL_I915_GEM_GET_TILING,
2703 &get_tiling); 2659 &get_tiling);
2704 if (ret != 0) { 2660 if (ret != 0) {
2661 DBG("create_from_prime: failed to get tiling: %s\n", strerror(errno));
2705 drm_intel_gem_bo_unreference(&bo_gem->bo); 2662 drm_intel_gem_bo_unreference(&bo_gem->bo);
2706 return NULL; 2663 return NULL;
2707 } 2664 }
2708 bo_gem->tiling_mode = get_tiling.tiling_mode; 2665 bo_gem->tiling_mode = get_tiling.tiling_mode;
2709 bo_gem->swizzle_mode = get_tiling.swizzle_mode; 2666 bo_gem->swizzle_mode = get_tiling.swizzle_mode;
2710 /* XXX stride is unknown */ 2667 /* XXX stride is unknown */
2711 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem); 2668 drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
2712 2669
2713 return &bo_gem->bo; 2670 return &bo_gem->bo;
2714} 2671}
2715 2672
2716drm_public int 2673int
2717drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd) 2674drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd)
2718{ 2675{
2719 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; 2676 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -2743,7 +2700,7 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
2743 if (!bo_gem->global_name) { 2700 if (!bo_gem->global_name) {
2744 struct drm_gem_flink flink; 2701 struct drm_gem_flink flink;
2745 2702
2746 VG_CLEAR(flink); 2703 memclear(flink);
2747 flink.handle = bo_gem->gem_handle; 2704 flink.handle = bo_gem->gem_handle;
2748 2705
2749 pthread_mutex_lock(&bufmgr_gem->lock); 2706 pthread_mutex_lock(&bufmgr_gem->lock);
@@ -2773,7 +2730,7 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
2773 * size is only bounded by how many buffers of that size we've managed to have 2730 * size is only bounded by how many buffers of that size we've managed to have
2774 * in flight at once. 2731 * in flight at once.
2775 */ 2732 */
2776drm_public void 2733void
2777drm_intel_bufmgr_gem_enable_reuse(drm_intel_bufmgr *bufmgr) 2734drm_intel_bufmgr_gem_enable_reuse(drm_intel_bufmgr *bufmgr)
2778{ 2735{
2779 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr; 2736 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
@@ -2788,7 +2745,7 @@ drm_intel_bufmgr_gem_enable_reuse(drm_intel_bufmgr *bufmgr)
2788 * allocation. If this option is not enabled, all relocs will have fence 2745 * allocation. If this option is not enabled, all relocs will have fence
2789 * register allocated. 2746 * register allocated.
2790 */ 2747 */
2791drm_public void 2748void
2792drm_intel_bufmgr_gem_enable_fenced_relocs(drm_intel_bufmgr *bufmgr) 2749drm_intel_bufmgr_gem_enable_fenced_relocs(drm_intel_bufmgr *bufmgr)
2793{ 2750{
2794 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr; 2751 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3005,6 +2962,13 @@ _drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
3005 return 1; 2962 return 1;
3006 } 2963 }
3007 2964
2965 for (i = 0; i< bo_gem->softpin_target_count; i++) {
2966 if (bo_gem->softpin_target[i] == target_bo)
2967 return 1;
2968 if (_drm_intel_gem_bo_references(bo_gem->softpin_target[i], target_bo))
2969 return 1;
2970 }
2971
3008 return 0; 2972 return 0;
3009} 2973}
3010 2974
@@ -3060,7 +3024,7 @@ init_cache_buckets(drm_intel_bufmgr_gem *bufmgr_gem)
3060 } 3024 }
3061} 3025}
3062 3026
3063drm_public void 3027void
3064drm_intel_bufmgr_gem_set_vma_cache_size(drm_intel_bufmgr *bufmgr, int limit) 3028drm_intel_bufmgr_gem_set_vma_cache_size(drm_intel_bufmgr *bufmgr, int limit)
3065{ 3029{
3066 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr; 3030 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3078,7 +3042,7 @@ static int
3078get_pci_device_id(drm_intel_bufmgr_gem *bufmgr_gem) 3042get_pci_device_id(drm_intel_bufmgr_gem *bufmgr_gem)
3079{ 3043{
3080 char *devid_override; 3044 char *devid_override;
3081 int devid; 3045 int devid = 0;
3082 int ret; 3046 int ret;
3083 drm_i915_getparam_t gp; 3047 drm_i915_getparam_t gp;
3084 3048
@@ -3090,8 +3054,7 @@ get_pci_device_id(drm_intel_bufmgr_gem *bufmgr_gem)
3090 } 3054 }
3091 } 3055 }
3092 3056
3093 VG_CLEAR(devid); 3057 memclear(gp);
3094 VG_CLEAR(gp);
3095 gp.param = I915_PARAM_CHIPSET_ID; 3058 gp.param = I915_PARAM_CHIPSET_ID;
3096 gp.value = &devid; 3059 gp.value = &devid;
3097 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp); 3060 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
@@ -3102,7 +3065,7 @@ get_pci_device_id(drm_intel_bufmgr_gem *bufmgr_gem)
3102 return devid; 3065 return devid;
3103} 3066}
3104 3067
3105drm_public int 3068int
3106drm_intel_bufmgr_gem_get_devid(drm_intel_bufmgr *bufmgr) 3069drm_intel_bufmgr_gem_get_devid(drm_intel_bufmgr *bufmgr)
3107{ 3070{
3108 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr; 3071 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3116,15 +3079,10 @@ drm_intel_bufmgr_gem_get_devid(drm_intel_bufmgr *bufmgr)
3116 * This function has to be called before drm_intel_bufmgr_gem_set_aub_dump() 3079 * This function has to be called before drm_intel_bufmgr_gem_set_aub_dump()
3117 * for it to have any effect. 3080 * for it to have any effect.
3118 */ 3081 */
3119drm_public void 3082void
3120drm_intel_bufmgr_gem_set_aub_filename(drm_intel_bufmgr *bufmgr, 3083drm_intel_bufmgr_gem_set_aub_filename(drm_intel_bufmgr *bufmgr,
3121 const char *filename) 3084 const char *filename)
3122{ 3085{
3123 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
3124
3125 free(bufmgr_gem->aub_filename);
3126 if (filename)
3127 bufmgr_gem->aub_filename = strdup(filename);
3128} 3086}
3129 3087
3130/** 3088/**
@@ -3135,64 +3093,17 @@ drm_intel_bufmgr_gem_set_aub_filename(drm_intel_bufmgr *bufmgr,
3135 * You can set up a GTT and upload your objects into the referenced 3093 * You can set up a GTT and upload your objects into the referenced
3136 * space, then send off batchbuffers and get BMPs out the other end. 3094 * space, then send off batchbuffers and get BMPs out the other end.
3137 */ 3095 */
3138drm_public void 3096void
3139drm_intel_bufmgr_gem_set_aub_dump(drm_intel_bufmgr *bufmgr, int enable) 3097drm_intel_bufmgr_gem_set_aub_dump(drm_intel_bufmgr *bufmgr, int enable)
3140{ 3098{
3141 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr; 3099 fprintf(stderr, "libdrm aub dumping is deprecated.\n\n"
3142 int entry = 0x200003; 3100 "Use intel_aubdump from intel-gpu-tools instead. Install intel-gpu-tools,\n"
3143 int i; 3101 "then run (for example)\n\n"
3144 int gtt_size = 0x10000; 3102 "\t$ intel_aubdump --output=trace.aub glxgears -geometry 500x500\n\n"
3145 const char *filename; 3103 "See the intel_aubdump man page for more details.\n");
3146
3147 if (!enable) {
3148 if (bufmgr_gem->aub_file) {
3149 fclose(bufmgr_gem->aub_file);
3150 bufmgr_gem->aub_file = NULL;
3151 }
3152 return;
3153 }
3154
3155 if (geteuid() != getuid())
3156 return;
3157
3158 if (bufmgr_gem->aub_filename)
3159 filename = bufmgr_gem->aub_filename;
3160 else
3161 filename = "intel.aub";
3162 bufmgr_gem->aub_file = fopen(filename, "w+");
3163 if (!bufmgr_gem->aub_file)
3164 return;
3165
3166 /* Start allocating objects from just after the GTT. */
3167 bufmgr_gem->aub_offset = gtt_size;
3168
3169 /* Start with a (required) version packet. */
3170 aub_out(bufmgr_gem, CMD_AUB_HEADER | (13 - 2));
3171 aub_out(bufmgr_gem,
3172 (4 << AUB_HEADER_MAJOR_SHIFT) |
3173 (0 << AUB_HEADER_MINOR_SHIFT));
3174 for (i = 0; i < 8; i++) {
3175 aub_out(bufmgr_gem, 0); /* app name */
3176 }
3177 aub_out(bufmgr_gem, 0); /* timestamp */
3178 aub_out(bufmgr_gem, 0); /* timestamp */
3179 aub_out(bufmgr_gem, 0); /* comment len */
3180
3181 /* Set up the GTT. The max we can handle is 256M */
3182 aub_out(bufmgr_gem, CMD_AUB_TRACE_HEADER_BLOCK | ((bufmgr_gem->gen >= 8 ? 6 : 5) - 2));
3183 /* Need to use GTT_ENTRY type for recent emulator */
3184 aub_out(bufmgr_gem, AUB_TRACE_MEMTYPE_GTT_ENTRY | 0 | AUB_TRACE_OP_DATA_WRITE);
3185 aub_out(bufmgr_gem, 0); /* subtype */
3186 aub_out(bufmgr_gem, 0); /* offset */
3187 aub_out(bufmgr_gem, gtt_size); /* size */
3188 if (bufmgr_gem->gen >= 8)
3189 aub_out(bufmgr_gem, 0);
3190 for (i = 0x000; i < gtt_size; i += 4, entry += 0x1000) {
3191 aub_out(bufmgr_gem, entry);
3192 }
3193} 3104}
3194 3105
3195drm_public drm_intel_context * 3106drm_intel_context *
3196drm_intel_gem_context_create(drm_intel_bufmgr *bufmgr) 3107drm_intel_gem_context_create(drm_intel_bufmgr *bufmgr)
3197{ 3108{
3198 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr; 3109 drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3204,7 +3115,7 @@ drm_intel_gem_context_create(drm_intel_bufmgr *bufmgr)
3204 if (!context) 3115 if (!context)
3205 return NULL; 3116 return NULL;
3206 3117
3207 VG_CLEAR(create); 3118 memclear(create);
3208 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create); 3119 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create);
3209 if (ret != 0) { 3120 if (ret != 0) {
3210 DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n", 3121 DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n",
@@ -3219,7 +3130,7 @@ drm_intel_gem_context_create(drm_intel_bufmgr *bufmgr)
3219 return context; 3130 return context;
3220} 3131}
3221 3132
3222drm_public void 3133void
3223drm_intel_gem_context_destroy(drm_intel_context *ctx) 3134drm_intel_gem_context_destroy(drm_intel_context *ctx)
3224{ 3135{
3225 drm_intel_bufmgr_gem *bufmgr_gem; 3136 drm_intel_bufmgr_gem *bufmgr_gem;
@@ -3229,7 +3140,7 @@ drm_intel_gem_context_destroy(drm_intel_context *ctx)
3229 if (ctx == NULL) 3140 if (ctx == NULL)
3230 return; 3141 return;
3231 3142
3232 VG_CLEAR(destroy); 3143 memclear(destroy);
3233 3144
3234 bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr; 3145 bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr;
3235 destroy.ctx_id = ctx->ctx_id; 3146 destroy.ctx_id = ctx->ctx_id;
@@ -3242,7 +3153,7 @@ drm_intel_gem_context_destroy(drm_intel_context *ctx)
3242 free(ctx); 3153 free(ctx);
3243} 3154}
3244 3155
3245drm_public int 3156int
3246drm_intel_get_reset_stats(drm_intel_context *ctx, 3157drm_intel_get_reset_stats(drm_intel_context *ctx,
3247 uint32_t *reset_count, 3158 uint32_t *reset_count,
3248 uint32_t *active, 3159 uint32_t *active,
@@ -3255,7 +3166,7 @@ drm_intel_get_reset_stats(drm_intel_context *ctx,
3255 if (ctx == NULL) 3166 if (ctx == NULL)
3256 return -EINVAL; 3167 return -EINVAL;
3257 3168
3258 memset(&stats, 0, sizeof(stats)); 3169 memclear(stats);
3259 3170
3260 bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr; 3171 bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr;
3261 stats.ctx_id = ctx->ctx_id; 3172 stats.ctx_id = ctx->ctx_id;
@@ -3276,7 +3187,7 @@ drm_intel_get_reset_stats(drm_intel_context *ctx,
3276 return ret; 3187 return ret;
3277} 3188}
3278 3189
3279drm_public int 3190int
3280drm_intel_reg_read(drm_intel_bufmgr *bufmgr, 3191drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
3281 uint32_t offset, 3192 uint32_t offset,
3282 uint64_t *result) 3193 uint64_t *result)
@@ -3285,7 +3196,7 @@ drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
3285 struct drm_i915_reg_read reg_read; 3196 struct drm_i915_reg_read reg_read;
3286 int ret; 3197 int ret;
3287 3198
3288 VG_CLEAR(reg_read); 3199 memclear(reg_read);
3289 reg_read.offset = offset; 3200 reg_read.offset = offset;
3290 3201
3291 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_REG_READ, &reg_read); 3202 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_REG_READ, &reg_read);
@@ -3294,6 +3205,37 @@ drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
3294 return ret; 3205 return ret;
3295} 3206}
3296 3207
3208int
3209drm_intel_get_subslice_total(int fd, unsigned int *subslice_total)
3210{
3211 drm_i915_getparam_t gp;
3212 int ret;
3213
3214 memclear(gp);
3215 gp.value = (int*)subslice_total;
3216 gp.param = I915_PARAM_SUBSLICE_TOTAL;
3217 ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
3218 if (ret)
3219 return -errno;
3220
3221 return 0;
3222}
3223
3224int
3225drm_intel_get_eu_total(int fd, unsigned int *eu_total)
3226{
3227 drm_i915_getparam_t gp;
3228 int ret;
3229
3230 memclear(gp);
3231 gp.value = (int*)eu_total;
3232 gp.param = I915_PARAM_EU_TOTAL;
3233 ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
3234 if (ret)
3235 return -errno;
3236
3237 return 0;
3238}
3297 3239
3298/** 3240/**
3299 * Annotate the given bo for use in aub dumping. 3241 * Annotate the given bo for use in aub dumping.
@@ -3316,24 +3258,11 @@ drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
3316 * default state (no annotations), call this function with a \c count 3258 * default state (no annotations), call this function with a \c count
3317 * of zero. 3259 * of zero.
3318 */ 3260 */
3319drm_public void 3261void
3320drm_intel_bufmgr_gem_set_aub_annotations(drm_intel_bo *bo, 3262drm_intel_bufmgr_gem_set_aub_annotations(drm_intel_bo *bo,
3321 drm_intel_aub_annotation *annotations, 3263 drm_intel_aub_annotation *annotations,
3322 unsigned count) 3264 unsigned count)
3323{ 3265{
3324 drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
3325 unsigned size = sizeof(*annotations) * count;
3326 drm_intel_aub_annotation *new_annotations =
3327 count > 0 ? realloc(bo_gem->aub_annotations, size) : NULL;
3328 if (new_annotations == NULL) {
3329 free(bo_gem->aub_annotations);
3330 bo_gem->aub_annotations = NULL;
3331 bo_gem->aub_annotation_count = 0;
3332 return;
3333 }
3334 memcpy(new_annotations, annotations, size);
3335 bo_gem->aub_annotations = new_annotations;
3336 bo_gem->aub_annotation_count = count;
3337} 3266}
3338 3267
3339static pthread_mutex_t bufmgr_list_mutex = PTHREAD_MUTEX_INITIALIZER; 3268static pthread_mutex_t bufmgr_list_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -3371,59 +3300,13 @@ drm_intel_bufmgr_gem_unref(drm_intel_bufmgr *bufmgr)
3371 } 3300 }
3372} 3301}
3373 3302
3374static bool
3375has_userptr(drm_intel_bufmgr_gem *bufmgr_gem)
3376{
3377 int ret;
3378 void *ptr;
3379 long pgsz;
3380 struct drm_i915_gem_userptr userptr;
3381 struct drm_gem_close close_bo;
3382
3383 pgsz = sysconf(_SC_PAGESIZE);
3384 assert(pgsz > 0);
3385
3386 ret = posix_memalign(&ptr, pgsz, pgsz);
3387 if (ret) {
3388 DBG("Failed to get a page (%ld) for userptr detection!\n",
3389 pgsz);
3390 return false;
3391 }
3392
3393 memset(&userptr, 0, sizeof(userptr));
3394 userptr.user_ptr = (__u64)(unsigned long)ptr;
3395 userptr.user_size = pgsz;
3396
3397retry:
3398 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_USERPTR, &userptr);
3399 if (ret) {
3400 if (errno == ENODEV && userptr.flags == 0) {
3401 userptr.flags = I915_USERPTR_UNSYNCHRONIZED;
3402 goto retry;
3403 }
3404 free(ptr);
3405 return false;
3406 }
3407
3408 close_bo.handle = userptr.handle;
3409 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
3410 free(ptr);
3411 if (ret) {
3412 fprintf(stderr, "Failed to release test userptr object! (%d) "
3413 "i915 kernel driver may not be sane!\n", errno);
3414 return false;
3415 }
3416
3417 return true;
3418}
3419
3420/** 3303/**
3421 * Initializes the GEM buffer manager, which uses the kernel to allocate, map, 3304 * Initializes the GEM buffer manager, which uses the kernel to allocate, map,
3422 * and manage map buffer objections. 3305 * and manage map buffer objections.
3423 * 3306 *
3424 * \param fd File descriptor of the opened DRM device. 3307 * \param fd File descriptor of the opened DRM device.
3425 */ 3308 */
3426drm_public drm_intel_bufmgr * 3309drm_intel_bufmgr *
3427drm_intel_bufmgr_gem_init(int fd, int batch_size) 3310drm_intel_bufmgr_gem_init(int fd, int batch_size)
3428{ 3311{
3429 drm_intel_bufmgr_gem *bufmgr_gem; 3312 drm_intel_bufmgr_gem *bufmgr_gem;
@@ -3451,6 +3334,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
3451 goto exit; 3334 goto exit;
3452 } 3335 }
3453 3336
3337 memclear(aperture);
3454 ret = drmIoctl(bufmgr_gem->fd, 3338 ret = drmIoctl(bufmgr_gem->fd,
3455 DRM_IOCTL_I915_GEM_GET_APERTURE, 3339 DRM_IOCTL_I915_GEM_GET_APERTURE,
3456 &aperture); 3340 &aperture);
@@ -3500,7 +3384,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
3500 bufmgr_gem->gtt_size -= 256*1024*1024; 3384 bufmgr_gem->gtt_size -= 256*1024*1024;
3501 } 3385 }
3502 3386
3503 VG_CLEAR(gp); 3387 memclear(gp);
3504 gp.value = &tmp; 3388 gp.value = &tmp;
3505 3389
3506 gp.param = I915_PARAM_HAS_EXECBUF2; 3390 gp.param = I915_PARAM_HAS_EXECBUF2;
@@ -3520,9 +3404,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
3520 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp); 3404 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
3521 bufmgr_gem->has_relaxed_fencing = ret == 0; 3405 bufmgr_gem->has_relaxed_fencing = ret == 0;
3522 3406
3523 if (has_userptr(bufmgr_gem)) 3407 bufmgr_gem->bufmgr.bo_alloc_userptr = check_bo_alloc_userptr;
3524 bufmgr_gem->bufmgr.bo_alloc_userptr =
3525 drm_intel_gem_bo_alloc_userptr;
3526 3408
3527 gp.param = I915_PARAM_HAS_WAIT_TIMEOUT; 3409 gp.param = I915_PARAM_HAS_WAIT_TIMEOUT;
3528 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp); 3410 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
@@ -3543,6 +3425,11 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
3543 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp); 3425 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
3544 bufmgr_gem->has_vebox = (ret == 0) & (*gp.value > 0); 3426 bufmgr_gem->has_vebox = (ret == 0) & (*gp.value > 0);
3545 3427
3428 gp.param = I915_PARAM_HAS_EXEC_SOFTPIN;
3429 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
3430 if (ret == 0 && *gp.value > 0)
3431 bufmgr_gem->bufmgr.bo_set_softpin_offset = drm_intel_gem_bo_set_softpin_offset;
3432
3546 if (bufmgr_gem->gen < 4) { 3433 if (bufmgr_gem->gen < 4) {
3547 gp.param = I915_PARAM_NUM_FENCES_AVAIL; 3434 gp.param = I915_PARAM_NUM_FENCES_AVAIL;
3548 gp.value = &bufmgr_gem->available_fences; 3435 gp.value = &bufmgr_gem->available_fences;
@@ -3569,6 +3456,13 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
3569 } 3456 }
3570 } 3457 }
3571 3458
3459 if (bufmgr_gem->gen >= 8) {
3460 gp.param = I915_PARAM_HAS_ALIASING_PPGTT;
3461 ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
3462 if (ret == 0 && *gp.value == 3)
3463 bufmgr_gem->bufmgr.bo_use_48b_address_range = drm_intel_gem_bo_use_48b_address_range;
3464 }
3465
3572 /* Let's go with one relocation per every 2 dwords (but round down a bit 3466 /* Let's go with one relocation per every 2 dwords (but round down a bit
3573 * since a power of two will mean an extra page allocation for the reloc 3467 * since a power of two will mean an extra page allocation for the reloc
3574 * buffer). 3468 * buffer).
diff --git a/intel/intel_bufmgr_priv.h b/intel/intel_bufmgr_priv.h
index 59ebd186..7e360a0b 100644
--- a/intel/intel_bufmgr_priv.h
+++ b/intel/intel_bufmgr_priv.h
@@ -152,6 +152,20 @@ struct _drm_intel_bufmgr {
152 void (*destroy) (drm_intel_bufmgr *bufmgr); 152 void (*destroy) (drm_intel_bufmgr *bufmgr);
153 153
154 /** 154 /**
155 * Indicate if the buffer can be placed anywhere in the full ppgtt
156 * address range (2^48).
157 *
158 * Any resource used with flat/heapless (0x00000000-0xfffff000)
159 * General State Heap (GSH) or Intructions State Heap (ISH) must
160 * be in a 32-bit range. 48-bit range will only be used when explicitly
161 * requested.
162 *
163 * \param bo Buffer to set the use_48b_address_range flag.
164 * \param enable The flag value.
165 */
166 void (*bo_use_48b_address_range) (drm_intel_bo *bo, uint32_t enable);
167
168 /**
155 * Add relocation entry in reloc_buf, which will be updated with the 169 * Add relocation entry in reloc_buf, which will be updated with the
156 * target buffer's real offset on on command submission. 170 * target buffer's real offset on on command submission.
157 * 171 *
@@ -227,6 +241,13 @@ struct _drm_intel_bufmgr {
227 uint32_t * swizzle_mode); 241 uint32_t * swizzle_mode);
228 242
229 /** 243 /**
244 * Set the offset at which this buffer will be softpinned
245 * \param bo Buffer to set the softpin offset for
246 * \param offset Softpin offset
247 */
248 int (*bo_set_softpin_offset) (drm_intel_bo *bo, uint64_t offset);
249
250 /**
230 * Create a visible name for a buffer which can be used by other apps 251 * Create a visible name for a buffer which can be used by other apps
231 * 252 *
232 * \param buf Buffer to create a name for 253 * \param buf Buffer to create a name for
diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
index e22a8673..26fbee4d 100644
--- a/intel/intel_chipset.h
+++ b/intel/intel_chipset.h
@@ -165,21 +165,31 @@
165#define PCI_CHIP_CHERRYVIEW_2 0x22b2 165#define PCI_CHIP_CHERRYVIEW_2 0x22b2
166#define PCI_CHIP_CHERRYVIEW_3 0x22b3 166#define PCI_CHIP_CHERRYVIEW_3 0x22b3
167 167
168#define PCI_CHIP_SKYLAKE_ULT_GT2 0x1916 168#define PCI_CHIP_SKYLAKE_DT_GT1 0x1902
169#define PCI_CHIP_SKYLAKE_ULT_GT1 0x1906 169#define PCI_CHIP_SKYLAKE_ULT_GT1 0x1906
170#define PCI_CHIP_SKYLAKE_ULT_GT3 0x1926 170#define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A /* Reserved */
171#define PCI_CHIP_SKYLAKE_ULT_GT2F 0x1921 171#define PCI_CHIP_SKYLAKE_ULX_GT1 0x190E /* Reserved */
172#define PCI_CHIP_SKYLAKE_ULX_GT1 0x190E
173#define PCI_CHIP_SKYLAKE_ULX_GT2 0x191E
174#define PCI_CHIP_SKYLAKE_DT_GT2 0x1912 172#define PCI_CHIP_SKYLAKE_DT_GT2 0x1912
175#define PCI_CHIP_SKYLAKE_DT_GT1 0x1902 173#define PCI_CHIP_SKYLAKE_FUSED0_GT2 0x1913 /* Reserved */
174#define PCI_CHIP_SKYLAKE_FUSED1_GT2 0x1915 /* Reserved */
175#define PCI_CHIP_SKYLAKE_ULT_GT2 0x1916
176#define PCI_CHIP_SKYLAKE_FUSED2_GT2 0x1917 /* Reserved */
177#define PCI_CHIP_SKYLAKE_SRV_GT2 0x191A /* Reserved */
176#define PCI_CHIP_SKYLAKE_HALO_GT2 0x191B 178#define PCI_CHIP_SKYLAKE_HALO_GT2 0x191B
177#define PCI_CHIP_SKYLAKE_HALO_GT3 0x192B
178#define PCI_CHIP_SKYLAKE_HALO_GT1 0x190B
179#define PCI_CHIP_SKYLAKE_SRV_GT2 0x191A
180#define PCI_CHIP_SKYLAKE_SRV_GT3 0x192A
181#define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A
182#define PCI_CHIP_SKYLAKE_WKS_GT2 0x191D 179#define PCI_CHIP_SKYLAKE_WKS_GT2 0x191D
180#define PCI_CHIP_SKYLAKE_ULX_GT2 0x191E
181#define PCI_CHIP_SKYLAKE_MOBILE_GT2 0x1921 /* Reserved */
182#define PCI_CHIP_SKYLAKE_GT3 0x1926
183#define PCI_CHIP_SKYLAKE_HALO_GT3 0x192B /* Reserved */
184#define PCI_CHIP_SKYLAKE_SRV_GT4 0x192A
185#define PCI_CHIP_SKYLAKE_DT_GT4 0x1932
186#define PCI_CHIP_SKYLAKE_SRV_GT4X 0x193A
187#define PCI_CHIP_SKYLAKE_H_GT4 0x193B
188#define PCI_CHIP_SKYLAKE_WKS_GT4 0x193D
189
190#define PCI_CHIP_BROXTON_0 0x0A84
191#define PCI_CHIP_BROXTON_1 0x1A84
192#define PCI_CHIP_BROXTON_2 0x5A84
183 193
184#define IS_MOBILE(devid) ((devid) == PCI_CHIP_I855_GM || \ 194#define IS_MOBILE(devid) ((devid) == PCI_CHIP_I855_GM || \
185 (devid) == PCI_CHIP_I915_GM || \ 195 (devid) == PCI_CHIP_I915_GM || \
@@ -343,26 +353,39 @@
343#define IS_SKL_GT1(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT1 || \ 353#define IS_SKL_GT1(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT1 || \
344 (devid) == PCI_CHIP_SKYLAKE_ULX_GT1 || \ 354 (devid) == PCI_CHIP_SKYLAKE_ULX_GT1 || \
345 (devid) == PCI_CHIP_SKYLAKE_DT_GT1 || \ 355 (devid) == PCI_CHIP_SKYLAKE_DT_GT1 || \
346 (devid) == PCI_CHIP_SKYLAKE_HALO_GT1 || \
347 (devid) == PCI_CHIP_SKYLAKE_SRV_GT1) 356 (devid) == PCI_CHIP_SKYLAKE_SRV_GT1)
348 357
349#define IS_SKL_GT2(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT2 || \ 358#define IS_SKL_GT2(devid) ((devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \
350 (devid) == PCI_CHIP_SKYLAKE_ULT_GT2F || \ 359 (devid) == PCI_CHIP_SKYLAKE_FUSED0_GT2 || \
351 (devid) == PCI_CHIP_SKYLAKE_ULX_GT2 || \ 360 (devid) == PCI_CHIP_SKYLAKE_FUSED1_GT2 || \
352 (devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \ 361 (devid) == PCI_CHIP_SKYLAKE_ULT_GT2 || \
353 (devid) == PCI_CHIP_SKYLAKE_HALO_GT2 || \ 362 (devid) == PCI_CHIP_SKYLAKE_FUSED2_GT2 || \
354 (devid) == PCI_CHIP_SKYLAKE_SRV_GT2 || \ 363 (devid) == PCI_CHIP_SKYLAKE_SRV_GT2 || \
355 (devid) == PCI_CHIP_SKYLAKE_WKS_GT2) 364 (devid) == PCI_CHIP_SKYLAKE_HALO_GT2 || \
365 (devid) == PCI_CHIP_SKYLAKE_WKS_GT2 || \
366 (devid) == PCI_CHIP_SKYLAKE_ULX_GT2 || \
367 (devid) == PCI_CHIP_SKYLAKE_MOBILE_GT2)
368
369#define IS_SKL_GT3(devid) ((devid) == PCI_CHIP_SKYLAKE_GT3 || \
370 (devid) == PCI_CHIP_SKYLAKE_HALO_GT3)
356 371
357#define IS_SKL_GT3(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT3 || \ 372#define IS_SKL_GT4(devid) ((devid) == PCI_CHIP_SKYLAKE_SRV_GT4 || \
358 (devid) == PCI_CHIP_SKYLAKE_HALO_GT3 || \ 373 (devid) == PCI_CHIP_SKYLAKE_DT_GT4 || \
359 (devid) == PCI_CHIP_SKYLAKE_SRV_GT3) 374 (devid) == PCI_CHIP_SKYLAKE_SRV_GT4X || \
375 (devid) == PCI_CHIP_SKYLAKE_H_GT4 || \
376 (devid) == PCI_CHIP_SKYLAKE_WKS_GT4)
360 377
361#define IS_SKYLAKE(devid) (IS_SKL_GT1(devid) || \ 378#define IS_SKYLAKE(devid) (IS_SKL_GT1(devid) || \
362 IS_SKL_GT2(devid) || \ 379 IS_SKL_GT2(devid) || \
363 IS_SKL_GT3(devid)) 380 IS_SKL_GT3(devid) || \
381 IS_SKL_GT4(devid))
382
383#define IS_BROXTON(devid) ((devid) == PCI_CHIP_BROXTON_0 || \
384 (devid) == PCI_CHIP_BROXTON_1 || \
385 (devid) == PCI_CHIP_BROXTON_2)
364 386
365#define IS_GEN9(devid) IS_SKYLAKE(devid) 387#define IS_GEN9(devid) (IS_SKYLAKE(devid) || \
388 IS_BROXTON(devid))
366 389
367#define IS_9XX(dev) (IS_GEN3(dev) || \ 390#define IS_9XX(dev) (IS_GEN3(dev) || \
368 IS_GEN4(dev) || \ 391 IS_GEN4(dev) || \
diff --git a/intel/intel_decode.c b/intel/intel_decode.c
index 7d5cbe5a..e7aef742 100644
--- a/intel/intel_decode.c
+++ b/intel/intel_decode.c
@@ -33,11 +33,14 @@
33#include <stdarg.h> 33#include <stdarg.h>
34#include <string.h> 34#include <string.h>
35 35
36#include "libdrm.h" 36#include "libdrm_macros.h"
37#include "xf86drm.h" 37#include "xf86drm.h"
38#include "intel_chipset.h" 38#include "intel_chipset.h"
39#include "intel_bufmgr.h" 39#include "intel_bufmgr.h"
40 40
41/* The compiler throws ~90 warnings. Do not spam the build, until we fix them. */
42#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
43
41/* Struct for tracking drm_intel_decode state. */ 44/* Struct for tracking drm_intel_decode state. */
42struct drm_intel_decode { 45struct drm_intel_decode {
43 /** stdio file where the output should land. Defaults to stdout. */ 46 /** stdio file where the output should land. Defaults to stdout. */
@@ -3630,7 +3633,6 @@ decode_3d_965(struct drm_intel_decode *ctx)
3630 3633
3631 case 0x7a00: 3634 case 0x7a00:
3632 if (IS_GEN6(devid) || IS_GEN7(devid)) { 3635 if (IS_GEN6(devid) || IS_GEN7(devid)) {
3633 unsigned int i;
3634 if (len != 4 && len != 5) 3636 if (len != 4 && len != 5)
3635 fprintf(out, "Bad count in PIPE_CONTROL\n"); 3637 fprintf(out, "Bad count in PIPE_CONTROL\n");
3636 3638
@@ -3732,8 +3734,6 @@ decode_3d_965(struct drm_intel_decode *ctx)
3732 if (opcode_3d->func) { 3734 if (opcode_3d->func) {
3733 return opcode_3d->func(ctx); 3735 return opcode_3d->func(ctx);
3734 } else { 3736 } else {
3735 unsigned int i;
3736
3737 instr_out(ctx, 0, "%s\n", opcode_3d->name); 3737 instr_out(ctx, 0, "%s\n", opcode_3d->name);
3738 3738
3739 for (i = 1; i < len; i++) { 3739 for (i = 1; i < len; i++) {
@@ -3817,7 +3817,7 @@ decode_3d_i830(struct drm_intel_decode *ctx)
3817 return 1; 3817 return 1;
3818} 3818}
3819 3819
3820drm_public struct drm_intel_decode * 3820struct drm_intel_decode *
3821drm_intel_decode_context_alloc(uint32_t devid) 3821drm_intel_decode_context_alloc(uint32_t devid)
3822{ 3822{
3823 struct drm_intel_decode *ctx; 3823 struct drm_intel_decode *ctx;
@@ -3851,20 +3851,20 @@ drm_intel_decode_context_alloc(uint32_t devid)
3851 return ctx; 3851 return ctx;
3852} 3852}
3853 3853
3854drm_public void 3854void
3855drm_intel_decode_context_free(struct drm_intel_decode *ctx) 3855drm_intel_decode_context_free(struct drm_intel_decode *ctx)
3856{ 3856{
3857 free(ctx); 3857 free(ctx);
3858} 3858}
3859 3859
3860drm_public void 3860void
3861drm_intel_decode_set_dump_past_end(struct drm_intel_decode *ctx, 3861drm_intel_decode_set_dump_past_end(struct drm_intel_decode *ctx,
3862 int dump_past_end) 3862 int dump_past_end)
3863{ 3863{
3864 ctx->dump_past_end = !!dump_past_end; 3864 ctx->dump_past_end = !!dump_past_end;
3865} 3865}
3866 3866
3867drm_public void 3867void
3868drm_intel_decode_set_batch_pointer(struct drm_intel_decode *ctx, 3868drm_intel_decode_set_batch_pointer(struct drm_intel_decode *ctx,
3869 void *data, uint32_t hw_offset, int count) 3869 void *data, uint32_t hw_offset, int count)
3870{ 3870{
@@ -3873,7 +3873,7 @@ drm_intel_decode_set_batch_pointer(struct drm_intel_decode *ctx,
3873 ctx->base_count = count; 3873 ctx->base_count = count;
3874} 3874}
3875 3875
3876drm_public void 3876void
3877drm_intel_decode_set_head_tail(struct drm_intel_decode *ctx, 3877drm_intel_decode_set_head_tail(struct drm_intel_decode *ctx,
3878 uint32_t head, uint32_t tail) 3878 uint32_t head, uint32_t tail)
3879{ 3879{
@@ -3881,11 +3881,11 @@ drm_intel_decode_set_head_tail(struct drm_intel_decode *ctx,
3881 ctx->tail = tail; 3881 ctx->tail = tail;
3882} 3882}
3883 3883
3884drm_public void 3884void
3885drm_intel_decode_set_output_file(struct drm_intel_decode *ctx, 3885drm_intel_decode_set_output_file(struct drm_intel_decode *ctx,
3886 FILE *out) 3886 FILE *output)
3887{ 3887{
3888 ctx->out = out; 3888 ctx->out = output;
3889} 3889}
3890 3890
3891/** 3891/**
@@ -3895,7 +3895,7 @@ drm_intel_decode_set_output_file(struct drm_intel_decode *ctx,
3895 * \param count number of DWORDs to decode in the batch buffer 3895 * \param count number of DWORDs to decode in the batch buffer
3896 * \param hw_offset hardware address for the buffer 3896 * \param hw_offset hardware address for the buffer
3897 */ 3897 */
3898drm_public void 3898void
3899drm_intel_decode(struct drm_intel_decode *ctx) 3899drm_intel_decode(struct drm_intel_decode *ctx)
3900{ 3900{
3901 int ret; 3901 int ret;
diff --git a/intel/mm.c b/intel/mm.c
index 10697452..954e9dcb 100644
--- a/intel/mm.c
+++ b/intel/mm.c
@@ -22,13 +22,18 @@
22 * 22 *
23 */ 23 */
24 24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
25#include <stdlib.h> 29#include <stdlib.h>
26#include <assert.h> 30#include <assert.h>
27 31
28#include "xf86drm.h" 32#include "xf86drm.h"
33#include "libdrm_macros.h"
29#include "mm.h" 34#include "mm.h"
30 35
31void mmDumpMemInfo(const struct mem_block *heap) 36drm_private void mmDumpMemInfo(const struct mem_block *heap)
32{ 37{
33 drmMsg("Memory heap %p:\n", (void *)heap); 38 drmMsg("Memory heap %p:\n", (void *)heap);
34 if (heap == 0) { 39 if (heap == 0) {
@@ -54,7 +59,7 @@ void mmDumpMemInfo(const struct mem_block *heap)
54 drmMsg("End of memory blocks\n"); 59 drmMsg("End of memory blocks\n");
55} 60}
56 61
57struct mem_block *mmInit(int ofs, int size) 62drm_private struct mem_block *mmInit(int ofs, int size)
58{ 63{
59 struct mem_block *heap, *block; 64 struct mem_block *heap, *block;
60 65
@@ -159,8 +164,8 @@ static struct mem_block *SliceBlock(struct mem_block *p,
159 return p; 164 return p;
160} 165}
161 166
162struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2, 167drm_private struct mem_block *mmAllocMem(struct mem_block *heap, int size,
163 int startSearch) 168 int align2, int startSearch)
164{ 169{
165 struct mem_block *p; 170 struct mem_block *p;
166 const int mask = (1 << align2) - 1; 171 const int mask = (1 << align2) - 1;
@@ -191,18 +196,6 @@ struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2,
191 return p; 196 return p;
192} 197}
193 198
194struct mem_block *mmFindBlock(struct mem_block *heap, int start)
195{
196 struct mem_block *p;
197
198 for (p = heap->next; p != heap; p = p->next) {
199 if (p->ofs == start)
200 return p;
201 }
202
203 return NULL;
204}
205
206static int Join2Blocks(struct mem_block *p) 199static int Join2Blocks(struct mem_block *p)
207{ 200{
208 /* XXX there should be some assertions here */ 201 /* XXX there should be some assertions here */
@@ -227,7 +220,7 @@ static int Join2Blocks(struct mem_block *p)
227 return 0; 220 return 0;
228} 221}
229 222
230int mmFreeMem(struct mem_block *b) 223drm_private int mmFreeMem(struct mem_block *b)
231{ 224{
232 if (!b) 225 if (!b)
233 return 0; 226 return 0;
@@ -254,7 +247,7 @@ int mmFreeMem(struct mem_block *b)
254 return 0; 247 return 0;
255} 248}
256 249
257void mmDestroy(struct mem_block *heap) 250drm_private void mmDestroy(struct mem_block *heap)
258{ 251{
259 struct mem_block *p; 252 struct mem_block *p;
260 253
diff --git a/intel/mm.h b/intel/mm.h
index 8a5235b0..8d83743f 100644
--- a/intel/mm.h
+++ b/intel/mm.h
@@ -29,6 +29,12 @@
29#ifndef MM_H 29#ifndef MM_H
30#define MM_H 30#define MM_H
31 31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include "libdrm_macros.h"
37
32struct mem_block { 38struct mem_block {
33 struct mem_block *next, *prev; 39 struct mem_block *next, *prev;
34 struct mem_block *next_free, *prev_free; 40 struct mem_block *next_free, *prev_free;
@@ -38,21 +44,11 @@ struct mem_block {
38 unsigned int reserved:1; 44 unsigned int reserved:1;
39}; 45};
40 46
41/* Rename the variables in the drm copy of this code so that it doesn't
42 * conflict with mesa or whoever else has copied it around.
43 */
44#define mmInit drm_mmInit
45#define mmAllocMem drm_mmAllocMem
46#define mmFreeMem drm_mmFreeMem
47#define mmFindBlock drm_mmFindBlock
48#define mmDestroy drm_mmDestroy
49#define mmDumpMemInfo drm_mmDumpMemInfo
50
51/** 47/**
52 * input: total size in bytes 48 * input: total size in bytes
53 * return: a heap pointer if OK, NULL if error 49 * return: a heap pointer if OK, NULL if error
54 */ 50 */
55extern struct mem_block *mmInit(int ofs, int size); 51drm_private extern struct mem_block *mmInit(int ofs, int size);
56 52
57/** 53/**
58 * Allocate 'size' bytes with 2^align2 bytes alignment, 54 * Allocate 'size' bytes with 2^align2 bytes alignment,
@@ -64,31 +60,25 @@ extern struct mem_block *mmInit(int ofs, int size);
64 * startSearch = linear offset from start of heap to begin search 60 * startSearch = linear offset from start of heap to begin search
65 * return: pointer to the allocated block, 0 if error 61 * return: pointer to the allocated block, 0 if error
66 */ 62 */
67extern struct mem_block *mmAllocMem(struct mem_block *heap, int size, 63drm_private extern struct mem_block *mmAllocMem(struct mem_block *heap,
68 int align2, int startSearch); 64 int size, int align2,
65 int startSearch);
69 66
70/** 67/**
71 * Free block starts at offset 68 * Free block starts at offset
72 * input: pointer to a block 69 * input: pointer to a block
73 * return: 0 if OK, -1 if error 70 * return: 0 if OK, -1 if error
74 */ 71 */
75extern int mmFreeMem(struct mem_block *b); 72drm_private extern int mmFreeMem(struct mem_block *b);
76
77/**
78 * Free block starts at offset
79 * input: pointer to a heap, start offset
80 * return: pointer to a block
81 */
82extern struct mem_block *mmFindBlock(struct mem_block *heap, int start);
83 73
84/** 74/**
85 * destroy MM 75 * destroy MM
86 */ 76 */
87extern void mmDestroy(struct mem_block *mmInit); 77drm_private extern void mmDestroy(struct mem_block *mmInit);
88 78
89/** 79/**
90 * For debuging purpose. 80 * For debuging purpose.
91 */ 81 */
92extern void mmDumpMemInfo(const struct mem_block *mmInit); 82drm_private extern void mmDumpMemInfo(const struct mem_block *mmInit);
93 83
94#endif 84#endif
diff --git a/intel/test_decode.c b/intel/test_decode.c
index d7025f03..b4eddcd1 100644
--- a/intel/test_decode.c
+++ b/intel/test_decode.c
@@ -34,7 +34,7 @@
34#include <sys/stat.h> 34#include <sys/stat.h>
35#include <err.h> 35#include <err.h>
36 36
37#include "libdrm.h" 37#include "libdrm_macros.h"
38#include "intel_bufmgr.h" 38#include "intel_bufmgr.h"
39#include "intel_chipset.h" 39#include "intel_chipset.h"
40 40
@@ -56,7 +56,7 @@ read_file(const char *filename, void **ptr, size_t *size)
56 struct stat st; 56 struct stat st;
57 57
58 fd = open(filename, O_RDONLY); 58 fd = open(filename, O_RDONLY);
59 if (fd == -1) 59 if (fd < 0)
60 errx(1, "couldn't open `%s'", filename); 60 errx(1, "couldn't open `%s'", filename);
61 61
62 ret = fstat(fd, &st); 62 ret = fstat(fd, &st);
@@ -91,7 +91,10 @@ compare_batch(struct drm_intel_decode *ctx, const char *batch_filename)
91{ 91{
92 FILE *out = NULL; 92 FILE *out = NULL;
93 void *ptr, *ref_ptr, *batch_ptr; 93 void *ptr, *ref_ptr, *batch_ptr;
94 size_t size, ref_size, batch_size; 94#ifdef HAVE_OPEN_MEMSTREAM
95 size_t size;
96#endif
97 size_t ref_size, batch_size;
95 const char *ref_suffix = "-ref.txt"; 98 const char *ref_suffix = "-ref.txt";
96 char *ref_filename; 99 char *ref_filename;
97 100
diff --git a/libdrm.h b/libdrm_macros.h
index f982c844..b88fdcef 100644
--- a/libdrm.h
+++ b/libdrm_macros.h
@@ -25,10 +25,8 @@
25 25
26#if defined(HAVE_VISIBILITY) 26#if defined(HAVE_VISIBILITY)
27# define drm_private __attribute__((visibility("hidden"))) 27# define drm_private __attribute__((visibility("hidden")))
28# define drm_public __attribute__((visibility("default")))
29#else 28#else
30# define drm_private 29# define drm_private
31# define drm_public
32#endif 30#endif
33 31
34 32
@@ -45,7 +43,7 @@
45 43
46#include <sys/mman.h> 44#include <sys/mman.h>
47 45
48#if defined(ANDROID) 46#if defined(ANDROID) && !defined(__LP64__)
49#include <errno.h> /* for EINVAL */ 47#include <errno.h> /* for EINVAL */
50 48
51static inline void *drm_mmap(void *addr, size_t length, int prot, int flags, 49static inline void *drm_mmap(void *addr, size_t length, int prot, int flags,
diff --git a/libkms/Android.mk b/libkms/Android.mk
index 34c10f56..aafebb64 100644
--- a/libkms/Android.mk
+++ b/libkms/Android.mk
@@ -49,6 +49,7 @@ endif
49LOCAL_SRC_FILES := $(filter-out %.h,$(LOCAL_SRC_FILES)) 49LOCAL_SRC_FILES := $(filter-out %.h,$(LOCAL_SRC_FILES))
50 50
51LOCAL_MODULE := libkms 51LOCAL_MODULE := libkms
52LOCAL_MODULE_TAGS := optional
52LOCAL_SHARED_LIBRARIES := libdrm 53LOCAL_SHARED_LIBRARIES := libdrm
53 54
54include $(BUILD_SHARED_LIBRARY) 55include $(BUILD_SHARED_LIBRARY)
diff --git a/libkms/Makefile.am b/libkms/Makefile.am
index 4baf4fc9..6c0ab7a2 100644
--- a/libkms/Makefile.am
+++ b/libkms/Makefile.am
@@ -43,4 +43,5 @@ libkmsinclude_HEADERS = $(LIBKMS_H_FILES)
43pkgconfigdir = @pkgconfigdir@ 43pkgconfigdir = @pkgconfigdir@
44pkgconfig_DATA = libkms.pc 44pkgconfig_DATA = libkms.pc
45 45
46EXTRA_DIST = Android.mk 46TESTS = kms-symbol-check
47EXTRA_DIST = Android.mk $(TESTS)
diff --git a/libkms/api.c b/libkms/api.c
index b512c42d..354d8a2e 100644
--- a/libkms/api.c
+++ b/libkms/api.c
@@ -29,9 +29,12 @@
29#ifdef HAVE_CONFIG_H 29#ifdef HAVE_CONFIG_H
30#include "config.h" 30#include "config.h"
31#endif 31#endif
32
32#include <errno.h> 33#include <errno.h>
33#include <stdlib.h> 34#include <stdlib.h>
34#include <string.h> 35#include <string.h>
36
37#include "libdrm_macros.h"
35#include "internal.h" 38#include "internal.h"
36 39
37int kms_create(int fd, struct kms_driver **out) 40int kms_create(int fd, struct kms_driver **out)
diff --git a/libkms/dumb.c b/libkms/dumb.c
index f9c16e11..b95a072c 100644
--- a/libkms/dumb.c
+++ b/libkms/dumb.c
@@ -38,7 +38,7 @@
38 38
39#include <sys/ioctl.h> 39#include <sys/ioctl.h>
40#include "xf86drm.h" 40#include "xf86drm.h"
41#include "libdrm.h" 41#include "libdrm_macros.h"
42 42
43struct dumb_bo 43struct dumb_bo
44{ 44{
@@ -190,7 +190,7 @@ dumb_bo_destroy(struct kms_bo *_bo)
190 return 0; 190 return 0;
191} 191}
192 192
193int 193drm_private int
194dumb_create(int fd, struct kms_driver **out) 194dumb_create(int fd, struct kms_driver **out)
195{ 195{
196 struct kms_driver *kms; 196 struct kms_driver *kms;
diff --git a/libkms/exynos.c b/libkms/exynos.c
index 92e329cd..5de2e5a9 100644
--- a/libkms/exynos.c
+++ b/libkms/exynos.c
@@ -25,6 +25,7 @@
25#include <sys/ioctl.h> 25#include <sys/ioctl.h>
26#include "xf86drm.h" 26#include "xf86drm.h"
27 27
28#include "libdrm_macros.h"
28#include "exynos_drm.h" 29#include "exynos_drm.h"
29 30
30struct exynos_bo 31struct exynos_bo
@@ -124,7 +125,7 @@ static int
124exynos_bo_map(struct kms_bo *_bo, void **out) 125exynos_bo_map(struct kms_bo *_bo, void **out)
125{ 126{
126 struct exynos_bo *bo = (struct exynos_bo *)_bo; 127 struct exynos_bo *bo = (struct exynos_bo *)_bo;
127 struct drm_exynos_gem_map_off arg; 128 struct drm_mode_map_dumb arg;
128 void *map = NULL; 129 void *map = NULL;
129 int ret; 130 int ret;
130 131
@@ -137,11 +138,11 @@ exynos_bo_map(struct kms_bo *_bo, void **out)
137 memset(&arg, 0, sizeof(arg)); 138 memset(&arg, 0, sizeof(arg));
138 arg.handle = bo->base.handle; 139 arg.handle = bo->base.handle;
139 140
140 ret = drmCommandWriteRead(bo->base.kms->fd, DRM_EXYNOS_GEM_MAP_OFFSET, &arg, sizeof(arg)); 141 ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
141 if (ret) 142 if (ret)
142 return ret; 143 return ret;
143 144
144 map = mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset); 145 map = drm_mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset);
145 if (map == MAP_FAILED) 146 if (map == MAP_FAILED)
146 return -errno; 147 return -errno;
147 148
@@ -184,7 +185,7 @@ exynos_bo_destroy(struct kms_bo *_bo)
184 return 0; 185 return 0;
185} 186}
186 187
187int 188drm_private int
188exynos_create(int fd, struct kms_driver **out) 189exynos_create(int fd, struct kms_driver **out)
189{ 190{
190 struct kms_driver *kms; 191 struct kms_driver *kms;
diff --git a/libkms/intel.c b/libkms/intel.c
index 51a7fd2e..3d8ca055 100644
--- a/libkms/intel.c
+++ b/libkms/intel.c
@@ -38,7 +38,7 @@
38 38
39#include <sys/ioctl.h> 39#include <sys/ioctl.h>
40#include "xf86drm.h" 40#include "xf86drm.h"
41#include "libdrm.h" 41#include "libdrm_macros.h"
42 42
43#include "i915_drm.h" 43#include "i915_drm.h"
44 44
@@ -216,7 +216,7 @@ intel_bo_destroy(struct kms_bo *_bo)
216 return 0; 216 return 0;
217} 217}
218 218
219int 219drm_private int
220intel_create(int fd, struct kms_driver **out) 220intel_create(int fd, struct kms_driver **out)
221{ 221{
222 struct kms_driver *kms; 222 struct kms_driver *kms;
diff --git a/libkms/internal.h b/libkms/internal.h
index f831b57d..905f5b17 100644
--- a/libkms/internal.h
+++ b/libkms/internal.h
@@ -29,6 +29,11 @@
29#ifndef INTERNAL_H_ 29#ifndef INTERNAL_H_
30#define INTERNAL_H_ 30#define INTERNAL_H_
31 31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include "libdrm_macros.h"
32#include "libkms.h" 37#include "libkms.h"
33 38
34struct kms_driver 39struct kms_driver
@@ -62,18 +67,18 @@ struct kms_bo
62 unsigned handle; 67 unsigned handle;
63}; 68};
64 69
65int linux_create(int fd, struct kms_driver **out); 70drm_private int linux_create(int fd, struct kms_driver **out);
66 71
67int vmwgfx_create(int fd, struct kms_driver **out); 72drm_private int vmwgfx_create(int fd, struct kms_driver **out);
68 73
69int intel_create(int fd, struct kms_driver **out); 74drm_private int intel_create(int fd, struct kms_driver **out);
70 75
71int dumb_create(int fd, struct kms_driver **out); 76drm_private int dumb_create(int fd, struct kms_driver **out);
72 77
73int nouveau_create(int fd, struct kms_driver **out); 78drm_private int nouveau_create(int fd, struct kms_driver **out);
74 79
75int radeon_create(int fd, struct kms_driver **out); 80drm_private int radeon_create(int fd, struct kms_driver **out);
76 81
77int exynos_create(int fd, struct kms_driver **out); 82drm_private int exynos_create(int fd, struct kms_driver **out);
78 83
79#endif 84#endif
diff --git a/libkms/kms-symbol-check b/libkms/kms-symbol-check
new file mode 100755
index 00000000..658b2692
--- /dev/null
+++ b/libkms/kms-symbol-check
@@ -0,0 +1,25 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.sources/LIBKMS_H_FILES
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libkms.so} | awk '{print $3}'| while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13kms_bo_create
14kms_bo_destroy
15kms_bo_get_prop
16kms_bo_map
17kms_bo_unmap
18kms_create
19kms_destroy
20kms_get_prop
21EOF
22done)
23
24test ! -n "$FUNCS" || echo $FUNCS
25test ! -n "$FUNCS"
diff --git a/libkms/libkms.h b/libkms/libkms.h
index c00b1597..930a2bfc 100644
--- a/libkms/libkms.h
+++ b/libkms/libkms.h
@@ -29,7 +29,7 @@
29#ifndef _LIBKMS_H_ 29#ifndef _LIBKMS_H_
30#define _LIBKMS_H_ 30#define _LIBKMS_H_
31 31
32#if defined(__cplusplus) || defined(c_plusplus) 32#if defined(__cplusplus)
33extern "C" { 33extern "C" {
34#endif 34#endif
35 35
@@ -75,7 +75,7 @@ int kms_bo_map(struct kms_bo *bo, void **out);
75int kms_bo_unmap(struct kms_bo *bo); 75int kms_bo_unmap(struct kms_bo *bo);
76int kms_bo_destroy(struct kms_bo **bo); 76int kms_bo_destroy(struct kms_bo **bo);
77 77
78#if defined(__cplusplus) || defined(c_plusplus) 78#if defined(__cplusplus)
79}; 79};
80#endif 80#endif
81 81
diff --git a/libkms/linux.c b/libkms/linux.c
index 77a0bbe9..6e0da830 100644
--- a/libkms/linux.c
+++ b/libkms/linux.c
@@ -39,9 +39,13 @@
39#include <xf86drm.h> 39#include <xf86drm.h>
40#include <string.h> 40#include <string.h>
41#include <unistd.h> 41#include <unistd.h>
42
43#include <sys/stat.h> 42#include <sys/stat.h>
43#include <sys/types.h>
44#ifdef HAVE_SYS_MKDEV_H
45#include <sys/mkdev.h>
46#endif
44 47
48#include "libdrm_macros.h"
45#include "internal.h" 49#include "internal.h"
46 50
47#define PATH_SIZE 512 51#define PATH_SIZE 512
@@ -145,7 +149,7 @@ struct create_record
145 int (*func)(int fd, struct kms_driver **out); 149 int (*func)(int fd, struct kms_driver **out);
146}; 150};
147 151
148static struct create_record table[] = { 152static const struct create_record table[] = {
149 { 0x8086, 0x2a42, intel_create }, /* i965 */ 153 { 0x8086, 0x2a42, intel_create }, /* i965 */
150#ifdef HAVE_VMWGFX 154#ifdef HAVE_VMWGFX
151 { 0x15ad, 0x0405, vmwgfx_create }, /* VMware vGPU */ 155 { 0x15ad, 0x0405, vmwgfx_create }, /* VMware vGPU */
@@ -225,7 +229,7 @@ linux_from_udev(int fd, struct kms_driver **out)
225} 229}
226#endif 230#endif
227 231
228int 232drm_private int
229linux_create(int fd, struct kms_driver **out) 233linux_create(int fd, struct kms_driver **out)
230{ 234{
231 if (!dumb_create(fd, out)) 235 if (!dumb_create(fd, out))
diff --git a/libkms/nouveau.c b/libkms/nouveau.c
index 228903ff..d10e0fdb 100644
--- a/libkms/nouveau.c
+++ b/libkms/nouveau.c
@@ -38,7 +38,7 @@
38 38
39#include <sys/ioctl.h> 39#include <sys/ioctl.h>
40#include "xf86drm.h" 40#include "xf86drm.h"
41#include "libdrm.h" 41#include "libdrm_macros.h"
42 42
43#include "nouveau_drm.h" 43#include "nouveau_drm.h"
44 44
@@ -198,7 +198,7 @@ nouveau_bo_destroy(struct kms_bo *_bo)
198 return 0; 198 return 0;
199} 199}
200 200
201int 201drm_private int
202nouveau_create(int fd, struct kms_driver **out) 202nouveau_create(int fd, struct kms_driver **out)
203{ 203{
204 struct kms_driver *kms; 204 struct kms_driver *kms;
diff --git a/libkms/radeon.c b/libkms/radeon.c
index 9383a0ae..aaeeaf31 100644
--- a/libkms/radeon.c
+++ b/libkms/radeon.c
@@ -38,7 +38,7 @@
38 38
39#include <sys/ioctl.h> 39#include <sys/ioctl.h>
40#include "xf86drm.h" 40#include "xf86drm.h"
41#include "libdrm.h" 41#include "libdrm_macros.h"
42 42
43#include "radeon_drm.h" 43#include "radeon_drm.h"
44 44
@@ -219,7 +219,7 @@ radeon_bo_destroy(struct kms_bo *_bo)
219 return 0; 219 return 0;
220} 220}
221 221
222int 222drm_private int
223radeon_create(int fd, struct kms_driver **out) 223radeon_create(int fd, struct kms_driver **out)
224{ 224{
225 struct kms_driver *kms; 225 struct kms_driver *kms;
diff --git a/libkms/vmwgfx.c b/libkms/vmwgfx.c
index bc04133f..6a24fd4d 100644
--- a/libkms/vmwgfx.c
+++ b/libkms/vmwgfx.c
@@ -36,7 +36,7 @@
36#include "internal.h" 36#include "internal.h"
37 37
38#include "xf86drm.h" 38#include "xf86drm.h"
39#include "libdrm.h" 39#include "libdrm_macros.h"
40#include "vmwgfx_drm.h" 40#include "vmwgfx_drm.h"
41 41
42struct vmwgfx_bo 42struct vmwgfx_bo
@@ -185,7 +185,7 @@ vmwgfx_bo_destroy(struct kms_bo *_bo)
185 return 0; 185 return 0;
186} 186}
187 187
188int 188drm_private int
189vmwgfx_create(int fd, struct kms_driver **out) 189vmwgfx_create(int fd, struct kms_driver **out)
190{ 190{
191 struct kms_driver *kms; 191 struct kms_driver *kms;
diff --git a/man/Makefile.am b/man/Makefile.am
index d25a2936..00eb4234 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,63 +1,62 @@
1# 1#
2# This generates man-pages out of the Docbook XML files. Simply add your files 2# This generates man-pages out of the Docbook XML files. Simply add your files
3# to the $MANPAGES array. If aliases are created, please add them to the 3# to the relevant *man_PRE array. If aliases are created, please add them to the
4# MANPAGES_ALIASES array so they get installed correctly. 4# *man_aliases_PRE array so they get installed correctly.
5# 5#
6 6
7MANPAGES = \ 7libman_PRE = \
8 drm.7 \ 8 drmAvailable.xml \
9 drm-kms.7 \ 9 drmHandleEvent.xml \
10 drm-memory.7 \ 10 drmModeGetResources.xml
11 drmAvailable.3 \
12 drmHandleEvent.3 \
13 drmModeGetResources.3
14MANPAGES_ALIASES = \
15 drm-mm.7 \
16 drm-gem.7 \
17 drm-ttm.7
18 11
19XML_FILES = \ 12miscman_PRE = \
20 $(patsubst %.1,%.xml,$(patsubst %.3,%.xml,$(patsubst %.5,%.xml,$(patsubst %.7,%.xml,$(MANPAGES))))) 13 drm.xml \
14 drm-kms.xml \
15 drm-memory.xml
21 16
22EXTRA_DIST = $(XML_FILES) 17miscman_aliases_PRE = \
23CLEANFILES = $(MANPAGES) $(MANPAGES_ALIASES) .man_fixup 18 drm-mm.xml \
24man_MANS = 19 drm-gem.xml \
20 drm-ttm.xml
21
22libmandir = $(LIB_MAN_DIR)
23miscmandir = $(MISC_MAN_DIR)
24miscman_aliasesdir = $(MISC_MAN_DIR)
25
26libman_DATA = $(libman_PRE:.xml=.$(LIB_MAN_SUFFIX))
27miscman_DATA = $(miscman_PRE:.xml=.$(MISC_MAN_SUFFIX))
28miscman_aliases_DATA = $(miscman_aliases_PRE:.xml=.$(MISC_MAN_SUFFIX))
29
30XML_FILES = \
31 $(libman_PRE) \
32 $(miscman_PRE)
25 33
26if BUILD_MANPAGES 34MAN_FILES = \
27if HAVE_MANPAGES_STYLESHEET 35 $(libman_DATA) \
36 $(miscman_DATA) \
37 $(miscman_aliases_DATA)
28 38
29man_MANS += $(MANPAGES) $(MANPAGES_ALIASES) 39EXTRA_DIST = $(XML_FILES)
40CLEANFILES = $(MAN_FILES)
30 41
31XSLTPROC_FLAGS = \ 42XSLTPROC_FLAGS = \
32 --stringparam man.authors.section.enabled 0 \ 43 --stringparam man.authors.section.enabled 0 \
33 --stringparam man.copyright.section.enabled 0 \ 44 --stringparam man.copyright.section.enabled 0 \
34 --stringparam funcsynopsis.style ansi \ 45 --stringparam funcsynopsis.style ansi \
35 --stringparam man.output.quietly 1 \ 46 --stringparam man.output.quietly 1 \
36 --nonet 47 --nonet \
48 $(MANPAGES_STYLESHEET)
37 49
38XSLTPROC_PROCESS_MAN = \ 50XSLTPROC_PROCESS_MAN = \
39 $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ 51 $(AM_V_GEN)$(XSLTPROC) -o "$@" $(XSLTPROC_FLAGS) "$<"
40 $(XSLTPROC) -o "$@" $(XSLTPROC_FLAGS) $(MANPAGES_STYLESHEET) "$<" && \
41 touch .man_fixup
42
43# Force .man_fixup if $(MANPAGES) are not built
44.man_fixup: | $(MANPAGES)
45 @touch .man_fixup
46 52
47$(MANPAGES_ALIASES): $(MANPAGES) .man_fixup 53$(miscman_aliases_DATA): $(miscman_DATA)
48 $(AM_V_GEN)if test -n "$@" ; then $(SED) -i -e 's/^\.so \([a-z_]\+\)\.\([0-9]\)$$/\.so man\2\/\1\.\2/' "$@" ; fi 54 $(AM_V_GEN)if test -n "$@" ; then $(SED) -i -e 's/^\.so \([a-z_]\+\)\.\([0-9]\)$$/\.so man\2\/\1\.\2/' "$@" ; fi
49 55
50%.1: $(top_srcdir)/man/%.xml 56SUFFIXES = .$(LIB_MAN_SUFFIX) .$(MISC_MAN_SUFFIX) .xml
51 $(XSLTPROC_PROCESS_MAN)
52
53%.3: $(top_srcdir)/man/%.xml
54 $(XSLTPROC_PROCESS_MAN)
55 57
56%.5: $(top_srcdir)/man/%.xml 58.xml.$(LIB_MAN_SUFFIX):
57 $(XSLTPROC_PROCESS_MAN) 59 $(XSLTPROC_PROCESS_MAN)
58 60
59%.7: $(top_srcdir)/man/%.xml 61.xml.$(MISC_MAN_SUFFIX):
60 $(XSLTPROC_PROCESS_MAN) 62 $(XSLTPROC_PROCESS_MAN)
61
62endif # HAVE_MANPAGES_STYLESHEET
63endif # BUILD_MANPAGES
diff --git a/nouveau/Android.mk b/nouveau/Android.mk
index 712c004a..19927973 100644
--- a/nouveau/Android.mk
+++ b/nouveau/Android.mk
@@ -13,7 +13,4 @@ LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_NOUVEAU_FILES))
13LOCAL_CFLAGS := \ 13LOCAL_CFLAGS := \
14 -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 14 -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1
15 15
16LOCAL_SHARED_LIBRARIES := \
17 libdrm
18
19include $(BUILD_SHARED_LIBRARY) 16include $(BUILD_SHARED_LIBRARY)
diff --git a/nouveau/Makefile.am b/nouveau/Makefile.am
index 7543e43c..76cdecad 100644
--- a/nouveau/Makefile.am
+++ b/nouveau/Makefile.am
@@ -2,9 +2,7 @@ include Makefile.sources
2 2
3AM_CFLAGS = \ 3AM_CFLAGS = \
4 $(WARN_CFLAGS) \ 4 $(WARN_CFLAGS) \
5 $(VISIBILITY_CFLAGS) \
6 -I$(top_srcdir) \ 5 -I$(top_srcdir) \
7 -I$(top_srcdir)/nouveau \
8 $(PTHREADSTUBS_CFLAGS) \ 6 $(PTHREADSTUBS_CFLAGS) \
9 -I$(top_srcdir)/include/drm \ 7 -I$(top_srcdir)/include/drm \
10 -DDEBUG 8 -DDEBUG
@@ -16,10 +14,20 @@ libdrm_nouveau_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
16 14
17libdrm_nouveau_la_SOURCES = $(LIBDRM_NOUVEAU_FILES) 15libdrm_nouveau_la_SOURCES = $(LIBDRM_NOUVEAU_FILES)
18 16
19libdrm_nouveauincludedir = ${includedir}/libdrm 17libdrm_nouveauincludedir = ${includedir}/libdrm/nouveau
20libdrm_nouveauinclude_HEADERS = $(LIBDRM_NOUVEAU_H_FILES) 18libdrm_nouveauinclude_HEADERS = $(LIBDRM_NOUVEAU_H_FILES)
21 19
20libdrm_nouveaunvifincludedir = ${includedir}/libdrm/nouveau/nvif
21libdrm_nouveaunvifinclude_HEADERS = nvif/class.h \
22 nvif/cl0080.h \
23 nvif/cl9097.h \
24 nvif/if0002.h \
25 nvif/if0003.h \
26 nvif/ioctl.h \
27 nvif/unpack.h
28
22pkgconfigdir = @pkgconfigdir@ 29pkgconfigdir = @pkgconfigdir@
23pkgconfig_DATA = libdrm_nouveau.pc 30pkgconfig_DATA = libdrm_nouveau.pc
24 31
25EXTRA_DIST = Android.mk 32TESTS = nouveau-symbol-check
33EXTRA_DIST = Android.mk $(TESTS)
diff --git a/nouveau/abi16.c b/nouveau/abi16.c
index ae13821b..ee38c0cb 100644
--- a/nouveau/abi16.c
+++ b/nouveau/abi16.c
@@ -29,19 +29,24 @@
29#include <stdlib.h> 29#include <stdlib.h>
30#include <stdint.h> 30#include <stdint.h>
31#include <stddef.h> 31#include <stddef.h>
32#include <errno.h>
32 33
33#include "private.h" 34#include "private.h"
34 35
36#include "nvif/class.h"
35 37
36int 38static int
37abi16_chan_nv04(struct nouveau_object *obj) 39abi16_chan_nv04(struct nouveau_object *obj)
38{ 40{
39 struct nouveau_device *dev = (struct nouveau_device *)obj->parent; 41 struct nouveau_drm *drm = nouveau_drm(obj);
40 struct nv04_fifo *nv04 = obj->data; 42 struct nv04_fifo *nv04 = obj->data;
41 struct drm_nouveau_channel_alloc req = {nv04->vram, nv04->gart}; 43 struct drm_nouveau_channel_alloc req = {
44 .fb_ctxdma_handle = nv04->vram,
45 .tt_ctxdma_handle = nv04->gart
46 };
42 int ret; 47 int ret;
43 48
44 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, 49 ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
45 &req, sizeof(req)); 50 &req, sizeof(req));
46 if (ret) 51 if (ret)
47 return ret; 52 return ret;
@@ -54,15 +59,15 @@ abi16_chan_nv04(struct nouveau_object *obj)
54 return 0; 59 return 0;
55} 60}
56 61
57int 62static int
58abi16_chan_nvc0(struct nouveau_object *obj) 63abi16_chan_nvc0(struct nouveau_object *obj)
59{ 64{
60 struct nouveau_device *dev = (struct nouveau_device *)obj->parent; 65 struct nouveau_drm *drm = nouveau_drm(obj);
61 struct drm_nouveau_channel_alloc req = {}; 66 struct drm_nouveau_channel_alloc req = {};
62 struct nvc0_fifo *nvc0 = obj->data; 67 struct nvc0_fifo *nvc0 = obj->data;
63 int ret; 68 int ret;
64 69
65 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, 70 ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
66 &req, sizeof(req)); 71 &req, sizeof(req));
67 if (ret) 72 if (ret)
68 return ret; 73 return ret;
@@ -75,10 +80,10 @@ abi16_chan_nvc0(struct nouveau_object *obj)
75 return 0; 80 return 0;
76} 81}
77 82
78int 83static int
79abi16_chan_nve0(struct nouveau_object *obj) 84abi16_chan_nve0(struct nouveau_object *obj)
80{ 85{
81 struct nouveau_device *dev = (struct nouveau_device *)obj->parent; 86 struct nouveau_drm *drm = nouveau_drm(obj);
82 struct drm_nouveau_channel_alloc req = {}; 87 struct drm_nouveau_channel_alloc req = {};
83 struct nve0_fifo *nve0 = obj->data; 88 struct nve0_fifo *nve0 = obj->data;
84 int ret; 89 int ret;
@@ -88,7 +93,7 @@ abi16_chan_nve0(struct nouveau_object *obj)
88 req.tt_ctxdma_handle = nve0->engine; 93 req.tt_ctxdma_handle = nve0->engine;
89 } 94 }
90 95
91 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, 96 ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
92 &req, sizeof(req)); 97 &req, sizeof(req));
93 if (ret) 98 if (ret)
94 return ret; 99 return ret;
@@ -101,17 +106,39 @@ abi16_chan_nve0(struct nouveau_object *obj)
101 return 0; 106 return 0;
102} 107}
103 108
104int 109static int
105abi16_engobj(struct nouveau_object *obj) 110abi16_engobj(struct nouveau_object *obj)
106{ 111{
112 struct nouveau_drm *drm = nouveau_drm(obj);
107 struct drm_nouveau_grobj_alloc req = { 113 struct drm_nouveau_grobj_alloc req = {
108 obj->parent->handle, obj->handle, obj->oclass 114 .channel = obj->parent->handle,
115 .handle = obj->handle,
116 .class = obj->oclass,
109 }; 117 };
110 struct nouveau_device *dev;
111 int ret; 118 int ret;
112 119
113 dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS); 120 /* Older kernel versions did not have the concept of nouveau-
114 ret = drmCommandWrite(dev->fd, DRM_NOUVEAU_GROBJ_ALLOC, 121 * specific classes and abused some NVIDIA-assigned ones for
122 * a SW class. The ABI16 layer has compatibility in place to
123 * translate these older identifiers to the newer ones.
124 *
125 * Clients that have been updated to use NVIF are required to
126 * use the newer class identifiers, which means that they'll
127 * break if running on an older kernel.
128 *
129 * To handle this case, when using ABI16, we translate to the
130 * older values which work on any kernel.
131 */
132 switch (req.class) {
133 case NVIF_CLASS_SW_NV04 : req.class = 0x006e; break;
134 case NVIF_CLASS_SW_NV10 : req.class = 0x016e; break;
135 case NVIF_CLASS_SW_NV50 : req.class = 0x506e; break;
136 case NVIF_CLASS_SW_GF100: req.class = 0x906e; break;
137 default:
138 break;
139 }
140
141 ret = drmCommandWrite(drm->fd, DRM_NOUVEAU_GROBJ_ALLOC,
115 &req, sizeof(req)); 142 &req, sizeof(req));
116 if (ret) 143 if (ret)
117 return ret; 144 return ret;
@@ -120,18 +147,19 @@ abi16_engobj(struct nouveau_object *obj)
120 return 0; 147 return 0;
121} 148}
122 149
123int 150static int
124abi16_ntfy(struct nouveau_object *obj) 151abi16_ntfy(struct nouveau_object *obj)
125{ 152{
153 struct nouveau_drm *drm = nouveau_drm(obj);
126 struct nv04_notify *ntfy = obj->data; 154 struct nv04_notify *ntfy = obj->data;
127 struct drm_nouveau_notifierobj_alloc req = { 155 struct drm_nouveau_notifierobj_alloc req = {
128 obj->parent->handle, ntfy->object->handle, ntfy->length 156 .channel = obj->parent->handle,
157 .handle = ntfy->object->handle,
158 .size = ntfy->length,
129 }; 159 };
130 struct nouveau_device *dev;
131 int ret; 160 int ret;
132 161
133 dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS); 162 ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
134 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
135 &req, sizeof(req)); 163 &req, sizeof(req));
136 if (ret) 164 if (ret)
137 return ret; 165 return ret;
@@ -141,7 +169,111 @@ abi16_ntfy(struct nouveau_object *obj)
141 return 0; 169 return 0;
142} 170}
143 171
144void 172drm_private int
173abi16_sclass(struct nouveau_object *obj, struct nouveau_sclass **psclass)
174{
175 struct nouveau_sclass *sclass;
176 struct nouveau_device *dev;
177
178 if (!(sclass = calloc(8, sizeof(*sclass))))
179 return -ENOMEM;
180 *psclass = sclass;
181
182 switch (obj->oclass) {
183 case NOUVEAU_FIFO_CHANNEL_CLASS:
184 /* Older kernel versions were exposing the wrong video engine
185 * classes on certain G98:GF100 boards. This has since been
186 * corrected, but ABI16 has compatibility in place to avoid
187 * breaking older userspace.
188 *
189 * Clients that have been updated to use NVIF are required to
190 * use the correct classes, which means that they'll break if
191 * running on an older kernel.
192 *
193 * To handle this issue, if using the older kernel interfaces,
194 * we'll magic up a list containing the vdec classes that the
195 * kernel will accept for these boards. Clients should make
196 * use of this information instead of hardcoding classes for
197 * specific chipsets.
198 */
199 dev = (struct nouveau_device *)obj->parent;
200 if (dev->chipset >= 0x98 &&
201 dev->chipset != 0xa0 &&
202 dev->chipset < 0xc0) {
203 *sclass++ = (struct nouveau_sclass){
204 GT212_MSVLD, -1, -1
205 };
206 *sclass++ = (struct nouveau_sclass){
207 GT212_MSPDEC, -1, -1
208 };
209 *sclass++ = (struct nouveau_sclass){
210 GT212_MSPPP, -1, -1
211 };
212 }
213 break;
214 default:
215 break;
216 }
217
218 return sclass - *psclass;
219}
220
221drm_private void
222abi16_delete(struct nouveau_object *obj)
223{
224 struct nouveau_drm *drm = nouveau_drm(obj);
225 if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
226 struct drm_nouveau_channel_free req;
227 req.channel = obj->handle;
228 drmCommandWrite(drm->fd, DRM_NOUVEAU_CHANNEL_FREE,
229 &req, sizeof(req));
230 } else {
231 struct drm_nouveau_gpuobj_free req;
232 req.channel = obj->parent->handle;
233 req.handle = obj->handle;
234 drmCommandWrite(drm->fd, DRM_NOUVEAU_GPUOBJ_FREE,
235 &req, sizeof(req));
236 }
237}
238
239drm_private bool
240abi16_object(struct nouveau_object *obj, int (**func)(struct nouveau_object *))
241{
242 struct nouveau_object *parent = obj->parent;
243
244 /* nouveau_object::length is (ab)used to determine whether the
245 * object is a legacy object (!=0), or a real NVIF object.
246 */
247 if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS) ||
248 (parent->length == 0 && parent->oclass == NV_DEVICE)) {
249 if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
250 struct nouveau_device *dev = (void *)parent;
251 if (dev->chipset < 0xc0)
252 *func = abi16_chan_nv04;
253 else
254 if (dev->chipset < 0xe0)
255 *func = abi16_chan_nvc0;
256 else
257 *func = abi16_chan_nve0;
258 return true;
259 }
260 } else
261 if ((parent->length != 0 &&
262 parent->oclass == NOUVEAU_FIFO_CHANNEL_CLASS)) {
263 if (obj->oclass == NOUVEAU_NOTIFIER_CLASS) {
264 *func = abi16_ntfy;
265 return true;
266 }
267
268 *func = abi16_engobj;
269 return false; /* try NVIF, if supported, before calling func */
270 }
271
272 *func = NULL;
273 return false;
274}
275
276drm_private void
145abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info) 277abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info)
146{ 278{
147 struct nouveau_bo_priv *nvbo = nouveau_bo(bo); 279 struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
@@ -175,11 +307,12 @@ abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info)
175 } 307 }
176} 308}
177 309
178int 310drm_private int
179abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment, 311abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
180 union nouveau_bo_config *config) 312 union nouveau_bo_config *config)
181{ 313{
182 struct nouveau_device *dev = bo->device; 314 struct nouveau_device *dev = bo->device;
315 struct nouveau_drm *drm = nouveau_drm(&dev->object);
183 struct drm_nouveau_gem_new req = {}; 316 struct drm_nouveau_gem_new req = {};
184 struct drm_nouveau_gem_info *info = &req.info; 317 struct drm_nouveau_gem_info *info = &req.info;
185 int ret; 318 int ret;
@@ -195,6 +328,9 @@ abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
195 if (bo->flags & NOUVEAU_BO_MAP) 328 if (bo->flags & NOUVEAU_BO_MAP)
196 info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE; 329 info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
197 330
331 if (bo->flags & NOUVEAU_BO_COHERENT)
332 info->domain |= NOUVEAU_GEM_DOMAIN_COHERENT;
333
198 if (!(bo->flags & NOUVEAU_BO_CONTIG)) 334 if (!(bo->flags & NOUVEAU_BO_CONTIG))
199 info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG; 335 info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG;
200 336
@@ -219,7 +355,7 @@ abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
219 if (!nouveau_device(dev)->have_bo_usage) 355 if (!nouveau_device(dev)->have_bo_usage)
220 info->tile_flags &= 0x0000ff00; 356 info->tile_flags &= 0x0000ff00;
221 357
222 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW, 358 ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_NEW,
223 &req, sizeof(req)); 359 &req, sizeof(req));
224 if (ret == 0) 360 if (ret == 0)
225 abi16_bo_info(bo, &req.info); 361 abi16_bo_info(bo, &req.info);
diff --git a/nouveau/bufctx.c b/nouveau/bufctx.c
index fdd3164f..4f76e5df 100644
--- a/nouveau/bufctx.c
+++ b/nouveau/bufctx.c
@@ -44,12 +44,6 @@ struct nouveau_bufref_priv {
44 struct nouveau_bufctx *bufctx; 44 struct nouveau_bufctx *bufctx;
45}; 45};
46 46
47static inline struct nouveau_bufref_priv *
48nouveau_bufref(struct nouveau_bufref *bctx)
49{
50 return (struct nouveau_bufref_priv *)bctx;
51}
52
53struct nouveau_bufbin_priv { 47struct nouveau_bufbin_priv {
54 struct nouveau_bufref_priv *list; 48 struct nouveau_bufref_priv *list;
55 int relocs; 49 int relocs;
@@ -68,7 +62,7 @@ nouveau_bufctx(struct nouveau_bufctx *bctx)
68 return (struct nouveau_bufctx_priv *)bctx; 62 return (struct nouveau_bufctx_priv *)bctx;
69} 63}
70 64
71drm_public int 65int
72nouveau_bufctx_new(struct nouveau_client *client, int bins, 66nouveau_bufctx_new(struct nouveau_client *client, int bins,
73 struct nouveau_bufctx **pbctx) 67 struct nouveau_bufctx **pbctx)
74{ 68{
@@ -88,7 +82,7 @@ nouveau_bufctx_new(struct nouveau_client *client, int bins,
88 return -ENOMEM; 82 return -ENOMEM;
89} 83}
90 84
91drm_public void 85void
92nouveau_bufctx_del(struct nouveau_bufctx **pbctx) 86nouveau_bufctx_del(struct nouveau_bufctx **pbctx)
93{ 87{
94 struct nouveau_bufctx_priv *pctx = nouveau_bufctx(*pbctx); 88 struct nouveau_bufctx_priv *pctx = nouveau_bufctx(*pbctx);
@@ -105,7 +99,7 @@ nouveau_bufctx_del(struct nouveau_bufctx **pbctx)
105 } 99 }
106} 100}
107 101
108drm_public void 102void
109nouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin) 103nouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin)
110{ 104{
111 struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx); 105 struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
@@ -123,7 +117,7 @@ nouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin)
123 pbin->relocs = 0; 117 pbin->relocs = 0;
124} 118}
125 119
126drm_public struct nouveau_bufref * 120struct nouveau_bufref *
127nouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin, 121nouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin,
128 struct nouveau_bo *bo, uint32_t flags) 122 struct nouveau_bo *bo, uint32_t flags)
129{ 123{
@@ -150,7 +144,7 @@ nouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin,
150 return &pref->base; 144 return &pref->base;
151} 145}
152 146
153drm_public struct nouveau_bufref * 147struct nouveau_bufref *
154nouveau_bufctx_mthd(struct nouveau_bufctx *bctx, int bin, uint32_t packet, 148nouveau_bufctx_mthd(struct nouveau_bufctx *bctx, int bin, uint32_t packet,
155 struct nouveau_bo *bo, uint64_t data, uint32_t flags, 149 struct nouveau_bo *bo, uint64_t data, uint32_t flags,
156 uint32_t vor, uint32_t tor) 150 uint32_t vor, uint32_t tor)
diff --git a/nouveau/libdrm_nouveau.pc.in b/nouveau/libdrm_nouveau.pc.in
index 9abfd811..7d0622e9 100644
--- a/nouveau/libdrm_nouveau.pc.in
+++ b/nouveau/libdrm_nouveau.pc.in
@@ -7,5 +7,5 @@ Name: libdrm_nouveau
7Description: Userspace interface to nouveau kernel DRM services 7Description: Userspace interface to nouveau kernel DRM services
8Version: @PACKAGE_VERSION@ 8Version: @PACKAGE_VERSION@
9Libs: -L${libdir} -ldrm_nouveau 9Libs: -L${libdir} -ldrm_nouveau
10Cflags: -I${includedir} -I${includedir}/libdrm 10Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/libdrm/nouveau
11Requires.private: libdrm 11Requires.private: libdrm
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
new file mode 100755
index 00000000..b265cea4
--- /dev/null
+++ b/nouveau/nouveau-symbol-check
@@ -0,0 +1,58 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.sources/LIBDRM_NOUVEAU_H_FILES
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_nouveau.so} | awk '{print $3}'| while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13nouveau_bo_map
14nouveau_bo_name_get
15nouveau_bo_name_ref
16nouveau_bo_new
17nouveau_bo_prime_handle_ref
18nouveau_bo_ref
19nouveau_bo_set_prime
20nouveau_bo_wait
21nouveau_bo_wrap
22nouveau_bufctx_del
23nouveau_bufctx_mthd
24nouveau_bufctx_new
25nouveau_bufctx_refn
26nouveau_bufctx_reset
27nouveau_client_del
28nouveau_client_new
29nouveau_device_del
30nouveau_device_new
31nouveau_device_open
32nouveau_device_open_existing
33nouveau_device_wrap
34nouveau_drm_del
35nouveau_drm_new
36nouveau_getparam
37nouveau_object_del
38nouveau_object_mclass
39nouveau_object_mthd
40nouveau_object_new
41nouveau_object_sclass_get
42nouveau_object_sclass_put
43nouveau_pushbuf_bufctx
44nouveau_pushbuf_data
45nouveau_pushbuf_del
46nouveau_pushbuf_kick
47nouveau_pushbuf_new
48nouveau_pushbuf_refd
49nouveau_pushbuf_refn
50nouveau_pushbuf_reloc
51nouveau_pushbuf_space
52nouveau_pushbuf_validate
53nouveau_setparam
54EOF
55done)
56
57test ! -n "$FUNCS" || echo $FUNCS
58test ! -n "$FUNCS"
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 5bc7c6d4..e113a8fe 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -38,15 +38,20 @@
38 38
39#include <xf86drm.h> 39#include <xf86drm.h>
40#include <xf86atomic.h> 40#include <xf86atomic.h>
41#include "libdrm.h" 41#include "libdrm_macros.h"
42#include "libdrm_lists.h" 42#include "libdrm_lists.h"
43#include "nouveau_drm.h" 43#include "nouveau_drm.h"
44 44
45#include "nouveau.h" 45#include "nouveau.h"
46#include "private.h" 46#include "private.h"
47 47
48#include "nvif/class.h"
49#include "nvif/cl0080.h"
50#include "nvif/ioctl.h"
51#include "nvif/unpack.h"
52
48#ifdef DEBUG 53#ifdef DEBUG
49uint32_t nouveau_debug = 0; 54drm_private uint32_t nouveau_debug = 0;
50 55
51static void 56static void
52debug_init(char *args) 57debug_init(char *args)
@@ -59,96 +64,429 @@ debug_init(char *args)
59} 64}
60#endif 65#endif
61 66
67static int
68nouveau_object_ioctl(struct nouveau_object *obj, void *data, uint32_t size)
69{
70 struct nouveau_drm *drm = nouveau_drm(obj);
71 union {
72 struct nvif_ioctl_v0 v0;
73 } *args = data;
74 uint32_t argc = size;
75 int ret = -ENOSYS;
76
77 if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
78 if (!obj->length) {
79 if (obj != &drm->client)
80 args->v0.object = (unsigned long)(void *)obj;
81 else
82 args->v0.object = 0;
83 args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
84 args->v0.route = 0x00;
85 } else {
86 args->v0.route = 0xff;
87 args->v0.token = obj->handle;
88 }
89 } else
90 return ret;
91
92 return drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NVIF, args, argc);
93}
94
95int
96nouveau_object_mthd(struct nouveau_object *obj,
97 uint32_t mthd, void *data, uint32_t size)
98{
99 struct nouveau_drm *drm = nouveau_drm(obj);
100 struct {
101 struct nvif_ioctl_v0 ioctl;
102 struct nvif_ioctl_mthd_v0 mthd;
103 } *args;
104 uint32_t argc = sizeof(*args) + size;
105 uint8_t stack[128];
106 int ret;
107
108 if (!drm->nvif)
109 return -ENOSYS;
110
111 if (argc > sizeof(stack)) {
112 if (!(args = malloc(argc)))
113 return -ENOMEM;
114 } else {
115 args = (void *)stack;
116 }
117 args->ioctl.version = 0;
118 args->ioctl.type = NVIF_IOCTL_V0_MTHD;
119 args->mthd.version = 0;
120 args->mthd.method = mthd;
121
122 memcpy(args->mthd.data, data, size);
123 ret = nouveau_object_ioctl(obj, args, argc);
124 memcpy(data, args->mthd.data, size);
125 if (args != (void *)stack)
126 free(args);
127 return ret;
128}
129
130void
131nouveau_object_sclass_put(struct nouveau_sclass **psclass)
132{
133 free(*psclass);
134 *psclass = NULL;
135}
136
137int
138nouveau_object_sclass_get(struct nouveau_object *obj,
139 struct nouveau_sclass **psclass)
140{
141 struct nouveau_drm *drm = nouveau_drm(obj);
142 struct {
143 struct nvif_ioctl_v0 ioctl;
144 struct nvif_ioctl_sclass_v0 sclass;
145 } *args = NULL;
146 struct nouveau_sclass *sclass;
147 int ret, cnt = 0, i;
148 uint32_t size;
149
150 if (!drm->nvif)
151 return abi16_sclass(obj, psclass);
152
153 while (1) {
154 size = sizeof(*args) + cnt * sizeof(args->sclass.oclass[0]);
155 if (!(args = malloc(size)))
156 return -ENOMEM;
157 args->ioctl.version = 0;
158 args->ioctl.type = NVIF_IOCTL_V0_SCLASS;
159 args->sclass.version = 0;
160 args->sclass.count = cnt;
161
162 ret = nouveau_object_ioctl(obj, args, size);
163 if (ret == 0 && args->sclass.count <= cnt)
164 break;
165 cnt = args->sclass.count;
166 free(args);
167 if (ret != 0)
168 return ret;
169 }
170
171 if ((sclass = calloc(args->sclass.count, sizeof(*sclass)))) {
172 for (i = 0; i < args->sclass.count; i++) {
173 sclass[i].oclass = args->sclass.oclass[i].oclass;
174 sclass[i].minver = args->sclass.oclass[i].minver;
175 sclass[i].maxver = args->sclass.oclass[i].maxver;
176 }
177 *psclass = sclass;
178 ret = args->sclass.count;
179 } else {
180 ret = -ENOMEM;
181 }
182
183 free(args);
184 return ret;
185}
186
187int
188nouveau_object_mclass(struct nouveau_object *obj,
189 const struct nouveau_mclass *mclass)
190{
191 struct nouveau_sclass *sclass;
192 int ret = -ENODEV;
193 int cnt, i, j;
194
195 cnt = nouveau_object_sclass_get(obj, &sclass);
196 if (cnt < 0)
197 return cnt;
198
199 for (i = 0; ret < 0 && mclass[i].oclass; i++) {
200 for (j = 0; j < cnt; j++) {
201 if (mclass[i].oclass == sclass[j].oclass &&
202 mclass[i].version >= sclass[j].minver &&
203 mclass[i].version <= sclass[j].maxver) {
204 ret = i;
205 break;
206 }
207 }
208 }
209
210 nouveau_object_sclass_put(&sclass);
211 return ret;
212}
213
214static void
215nouveau_object_fini(struct nouveau_object *obj)
216{
217 struct {
218 struct nvif_ioctl_v0 ioctl;
219 struct nvif_ioctl_del del;
220 } args = {
221 .ioctl.type = NVIF_IOCTL_V0_DEL,
222 };
223
224 if (obj->data) {
225 abi16_delete(obj);
226 free(obj->data);
227 obj->data = NULL;
228 return;
229 }
230
231 nouveau_object_ioctl(obj, &args, sizeof(args));
232}
233
234static int
235nouveau_object_init(struct nouveau_object *parent, uint32_t handle,
236 int32_t oclass, void *data, uint32_t size,
237 struct nouveau_object *obj)
238{
239 struct nouveau_drm *drm = nouveau_drm(parent);
240 struct {
241 struct nvif_ioctl_v0 ioctl;
242 struct nvif_ioctl_new_v0 new;
243 } *args;
244 uint32_t argc = sizeof(*args) + size;
245 int (*func)(struct nouveau_object *);
246 int ret = -ENOSYS;
247
248 obj->parent = parent;
249 obj->handle = handle;
250 obj->oclass = oclass;
251 obj->length = 0;
252 obj->data = NULL;
253
254 if (!abi16_object(obj, &func) && drm->nvif) {
255 if (!(args = malloc(argc)))
256 return -ENOMEM;
257 args->ioctl.version = 0;
258 args->ioctl.type = NVIF_IOCTL_V0_NEW;
259 args->new.version = 0;
260 args->new.route = NVIF_IOCTL_V0_ROUTE_NVIF;
261 args->new.token = (unsigned long)(void *)obj;
262 args->new.object = (unsigned long)(void *)obj;
263 args->new.handle = handle;
264 args->new.oclass = oclass;
265 memcpy(args->new.data, data, size);
266 ret = nouveau_object_ioctl(parent, args, argc);
267 memcpy(data, args->new.data, size);
268 free(args);
269 } else
270 if (func) {
271 obj->length = size ? size : sizeof(struct nouveau_object *);
272 if (!(obj->data = malloc(obj->length)))
273 return -ENOMEM;
274 if (data)
275 memcpy(obj->data, data, obj->length);
276 *(struct nouveau_object **)obj->data = obj;
277
278 ret = func(obj);
279 }
280
281 if (ret) {
282 nouveau_object_fini(obj);
283 return ret;
284 }
285
286 return 0;
287}
288
289int
290nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
291 uint32_t oclass, void *data, uint32_t length,
292 struct nouveau_object **pobj)
293{
294 struct nouveau_object *obj;
295 int ret;
296
297 if (!(obj = malloc(sizeof(*obj))))
298 return -ENOMEM;
299
300 ret = nouveau_object_init(parent, handle, oclass, data, length, obj);
301 if (ret) {
302 free(obj);
303 return ret;
304 }
305
306 *pobj = obj;
307 return 0;
308}
309
310void
311nouveau_object_del(struct nouveau_object **pobj)
312{
313 struct nouveau_object *obj = *pobj;
314 if (obj) {
315 nouveau_object_fini(obj);
316 free(obj);
317 *pobj = NULL;
318 }
319}
320
321void
322nouveau_drm_del(struct nouveau_drm **pdrm)
323{
324 free(*pdrm);
325 *pdrm = NULL;
326}
327
328int
329nouveau_drm_new(int fd, struct nouveau_drm **pdrm)
330{
331 struct nouveau_drm *drm;
332 drmVersionPtr ver;
333
334#ifdef DEBUG
335 debug_init(getenv("NOUVEAU_LIBDRM_DEBUG"));
336#endif
337
338 if (!(drm = calloc(1, sizeof(*drm))))
339 return -ENOMEM;
340 drm->fd = fd;
341
342 if (!(ver = drmGetVersion(fd))) {
343 nouveau_drm_del(&drm);
344 return -EINVAL;
345 }
346 *pdrm = drm;
347
348 drm->version = (ver->version_major << 24) |
349 (ver->version_minor << 8) |
350 ver->version_patchlevel;
351 drm->nvif = (drm->version >= 0x01000301);
352 drmFreeVersion(ver);
353 return 0;
354}
355
62/* this is the old libdrm's version of nouveau_device_wrap(), the symbol 356/* this is the old libdrm's version of nouveau_device_wrap(), the symbol
63 * is kept here to prevent AIGLX from crashing if the DDX is linked against 357 * is kept here to prevent AIGLX from crashing if the DDX is linked against
64 * the new libdrm, but the DRI driver against the old 358 * the new libdrm, but the DRI driver against the old
65 */ 359 */
66drm_public int 360int
67nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd, 361nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
68 drm_context_t ctx) 362 drm_context_t ctx)
69{ 363{
70 return -EACCES; 364 return -EACCES;
71} 365}
72 366
73drm_public int 367int
74nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) 368nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
369 void *data, uint32_t size, struct nouveau_device **pdev)
75{ 370{
76 struct nouveau_device_priv *nvdev = calloc(1, sizeof(*nvdev)); 371 struct nv_device_info_v0 info = {};
77 struct nouveau_device *dev = &nvdev->base; 372 union {
78 uint64_t chipset, vram, gart, bousage; 373 struct nv_device_v0 v0;
79 drmVersionPtr ver; 374 } *args = data;
80 int ret; 375 uint32_t argc = size;
376 struct nouveau_drm *drm = nouveau_drm(parent);
377 struct nouveau_device_priv *nvdev;
378 struct nouveau_device *dev;
379 uint64_t v;
81 char *tmp; 380 char *tmp;
381 int ret = -ENOSYS;
82 382
83#ifdef DEBUG 383 if (oclass != NV_DEVICE ||
84 debug_init(getenv("NOUVEAU_LIBDRM_DEBUG")); 384 nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))
85#endif 385 return ret;
86 386
87 if (!nvdev) 387 if (!(nvdev = calloc(1, sizeof(*nvdev))))
88 return -ENOMEM; 388 return -ENOMEM;
89 ret = pthread_mutex_init(&nvdev->lock, NULL); 389 dev = *pdev = &nvdev->base;
90 if (ret) { 390 dev->fd = -1;
91 free(nvdev);
92 return ret;
93 }
94 391
95 nvdev->base.fd = fd; 392 if (drm->nvif) {
393 ret = nouveau_object_init(parent, 0, oclass, args, argc,
394 &dev->object);
395 if (ret)
396 goto done;
96 397
97 ver = drmGetVersion(fd); 398 info.version = 0;
98 if (ver) dev->drm_version = (ver->version_major << 24) |
99 (ver->version_minor << 8) |
100 ver->version_patchlevel;
101 drmFreeVersion(ver);
102 399
103 if ( dev->drm_version != 0x00000010 && 400 ret = nouveau_object_mthd(&dev->object, NV_DEVICE_V0_INFO,
104 (dev->drm_version < 0x01000000 || 401 &info, sizeof(info));
105 dev->drm_version >= 0x02000000)) { 402 if (ret)
106 nouveau_device_del(&dev); 403 goto done;
107 return -EINVAL; 404
108 } 405 nvdev->base.chipset = info.chipset;
406 nvdev->have_bo_usage = true;
407 } else
408 if (args->v0.device == ~0ULL) {
409 nvdev->base.object.parent = &drm->client;
410 nvdev->base.object.handle = ~0ULL;
411 nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
412 nvdev->base.object.length = ~0;
413
414 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &v);
415 if (ret)
416 goto done;
417 nvdev->base.chipset = v;
109 418
110 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset); 419 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &v);
111 if (ret == 0) 420 if (ret == 0)
112 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &vram); 421 nvdev->have_bo_usage = (v != 0);
113 if (ret == 0) 422 } else
114 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &gart); 423 return -ENOSYS;
115 if (ret) {
116 nouveau_device_del(&dev);
117 return ret;
118 }
119 424
120 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &bousage); 425 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &v);
121 if (ret == 0) 426 if (ret)
122 nvdev->have_bo_usage = (bousage != 0); 427 goto done;
428 nvdev->base.vram_size = v;
123 429
124 nvdev->close = close; 430 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &v);
431 if (ret)
432 goto done;
433 nvdev->base.gart_size = v;
125 434
126 tmp = getenv("NOUVEAU_LIBDRM_VRAM_LIMIT_PERCENT"); 435 tmp = getenv("NOUVEAU_LIBDRM_VRAM_LIMIT_PERCENT");
127 if (tmp) 436 if (tmp)
128 nvdev->vram_limit_percent = atoi(tmp); 437 nvdev->vram_limit_percent = atoi(tmp);
129 else 438 else
130 nvdev->vram_limit_percent = 80; 439 nvdev->vram_limit_percent = 80;
440
441 nvdev->base.vram_limit =
442 (nvdev->base.vram_size * nvdev->vram_limit_percent) / 100;
443
131 tmp = getenv("NOUVEAU_LIBDRM_GART_LIMIT_PERCENT"); 444 tmp = getenv("NOUVEAU_LIBDRM_GART_LIMIT_PERCENT");
132 if (tmp) 445 if (tmp)
133 nvdev->gart_limit_percent = atoi(tmp); 446 nvdev->gart_limit_percent = atoi(tmp);
134 else 447 else
135 nvdev->gart_limit_percent = 80; 448 nvdev->gart_limit_percent = 80;
136 DRMINITLISTHEAD(&nvdev->bo_list); 449
137 nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
138 nvdev->base.lib_version = 0x01000000;
139 nvdev->base.chipset = chipset;
140 nvdev->base.vram_size = vram;
141 nvdev->base.gart_size = gart;
142 nvdev->base.vram_limit =
143 (nvdev->base.vram_size * nvdev->vram_limit_percent) / 100;
144 nvdev->base.gart_limit = 450 nvdev->base.gart_limit =
145 (nvdev->base.gart_size * nvdev->gart_limit_percent) / 100; 451 (nvdev->base.gart_size * nvdev->gart_limit_percent) / 100;
146 452
147 *pdev = &nvdev->base; 453 ret = pthread_mutex_init(&nvdev->lock, NULL);
454 DRMINITLISTHEAD(&nvdev->bo_list);
455done:
456 if (ret)
457 nouveau_device_del(pdev);
458 return ret;
459}
460
461int
462nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
463{
464 struct nouveau_drm *drm;
465 struct nouveau_device_priv *nvdev;
466 int ret;
467
468 ret = nouveau_drm_new(fd, &drm);
469 if (ret)
470 return ret;
471 drm->nvif = false;
472
473 ret = nouveau_device_new(&drm->client, NV_DEVICE,
474 &(struct nv_device_v0) {
475 .device = ~0ULL,
476 }, sizeof(struct nv_device_v0), pdev);
477 if (ret) {
478 nouveau_drm_del(&drm);
479 return ret;
480 }
481
482 nvdev = nouveau_device(*pdev);
483 nvdev->base.fd = drm->fd;
484 nvdev->base.drm_version = drm->version;
485 nvdev->close = close;
148 return 0; 486 return 0;
149} 487}
150 488
151drm_public int 489int
152nouveau_device_open(const char *busid, struct nouveau_device **pdev) 490nouveau_device_open(const char *busid, struct nouveau_device **pdev)
153{ 491{
154 int ret = -ENODEV, fd = drmOpen("nouveau", busid); 492 int ret = -ENODEV, fd = drmOpen("nouveau", busid);
@@ -160,38 +498,45 @@ nouveau_device_open(const char *busid, struct nouveau_device **pdev)
160 return ret; 498 return ret;
161} 499}
162 500
163drm_public void 501void
164nouveau_device_del(struct nouveau_device **pdev) 502nouveau_device_del(struct nouveau_device **pdev)
165{ 503{
166 struct nouveau_device_priv *nvdev = nouveau_device(*pdev); 504 struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
167 if (nvdev) { 505 if (nvdev) {
168 if (nvdev->close)
169 drmClose(nvdev->base.fd);
170 free(nvdev->client); 506 free(nvdev->client);
171 pthread_mutex_destroy(&nvdev->lock); 507 pthread_mutex_destroy(&nvdev->lock);
508 if (nvdev->base.fd >= 0) {
509 struct nouveau_drm *drm =
510 nouveau_drm(&nvdev->base.object);
511 nouveau_drm_del(&drm);
512 if (nvdev->close)
513 drmClose(nvdev->base.fd);
514 }
172 free(nvdev); 515 free(nvdev);
173 *pdev = NULL; 516 *pdev = NULL;
174 } 517 }
175} 518}
176 519
177drm_public int 520int
178nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value) 521nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
179{ 522{
180 struct drm_nouveau_getparam r = { param, 0 }; 523 struct nouveau_drm *drm = nouveau_drm(&dev->object);
181 int fd = dev->fd, ret = 524 struct drm_nouveau_getparam r = { .param = param };
525 int fd = drm->fd, ret =
182 drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &r, sizeof(r)); 526 drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &r, sizeof(r));
183 *value = r.value; 527 *value = r.value;
184 return ret; 528 return ret;
185} 529}
186 530
187drm_public int 531int
188nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value) 532nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value)
189{ 533{
190 struct drm_nouveau_setparam r = { param, value }; 534 struct nouveau_drm *drm = nouveau_drm(&dev->object);
191 return drmCommandWrite(dev->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r)); 535 struct drm_nouveau_setparam r = { .param = param, .value = value };
536 return drmCommandWrite(drm->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r));
192} 537}
193 538
194drm_public int 539int
195nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient) 540nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient)
196{ 541{
197 struct nouveau_device_priv *nvdev = nouveau_device(dev); 542 struct nouveau_device_priv *nvdev = nouveau_device(dev);
@@ -230,7 +575,7 @@ unlock:
230 return ret; 575 return ret;
231} 576}
232 577
233drm_public void 578void
234nouveau_client_del(struct nouveau_client **pclient) 579nouveau_client_del(struct nouveau_client **pclient)
235{ 580{
236 struct nouveau_client_priv *pcli = nouveau_client(*pclient); 581 struct nouveau_client_priv *pcli = nouveau_client(*pclient);
@@ -246,152 +591,42 @@ nouveau_client_del(struct nouveau_client **pclient)
246 } 591 }
247} 592}
248 593
249drm_public int
250nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
251 uint32_t oclass, void *data, uint32_t length,
252 struct nouveau_object **pobj)
253{
254 struct nouveau_device *dev;
255 struct nouveau_object *obj;
256 int ret = -EINVAL;
257
258 if (length == 0)
259 length = sizeof(struct nouveau_object *);
260 obj = malloc(sizeof(*obj) + length);
261 obj->parent = parent;
262 obj->handle = handle;
263 obj->oclass = oclass;
264 obj->length = length;
265 obj->data = obj + 1;
266 if (data)
267 memcpy(obj->data, data, length);
268 *(struct nouveau_object **)obj->data = obj;
269
270 dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
271 switch (parent->oclass) {
272 case NOUVEAU_DEVICE_CLASS:
273 switch (obj->oclass) {
274 case NOUVEAU_FIFO_CHANNEL_CLASS:
275 {
276 if (dev->chipset < 0xc0)
277 ret = abi16_chan_nv04(obj);
278 else
279 if (dev->chipset < 0xe0)
280 ret = abi16_chan_nvc0(obj);
281 else
282 ret = abi16_chan_nve0(obj);
283 }
284 break;
285 default:
286 break;
287 }
288 break;
289 case NOUVEAU_FIFO_CHANNEL_CLASS:
290 switch (obj->oclass) {
291 case NOUVEAU_NOTIFIER_CLASS:
292 ret = abi16_ntfy(obj);
293 break;
294 default:
295 ret = abi16_engobj(obj);
296 break;
297 }
298 default:
299 break;
300 }
301
302 if (ret) {
303 free(obj);
304 return ret;
305 }
306
307 *pobj = obj;
308 return 0;
309}
310
311drm_public void
312nouveau_object_del(struct nouveau_object **pobj)
313{
314 struct nouveau_object *obj = *pobj;
315 struct nouveau_device *dev;
316 if (obj) {
317 dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
318 if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
319 struct drm_nouveau_channel_free req;
320 req.channel = obj->handle;
321 drmCommandWrite(dev->fd, DRM_NOUVEAU_CHANNEL_FREE,
322 &req, sizeof(req));
323 } else {
324 struct drm_nouveau_gpuobj_free req;
325 req.channel = obj->parent->handle;
326 req.handle = obj->handle;
327 drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
328 &req, sizeof(req));
329 }
330 }
331 free(obj);
332 *pobj = NULL;
333}
334
335drm_public void *
336nouveau_object_find(struct nouveau_object *obj, uint32_t pclass)
337{
338 while (obj && obj->oclass != pclass) {
339 obj = obj->parent;
340 if (pclass == NOUVEAU_PARENT_CLASS)
341 break;
342 }
343 return obj;
344}
345
346static void 594static void
347nouveau_bo_del(struct nouveau_bo *bo) 595nouveau_bo_del(struct nouveau_bo *bo)
348{ 596{
597 struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
349 struct nouveau_device_priv *nvdev = nouveau_device(bo->device); 598 struct nouveau_device_priv *nvdev = nouveau_device(bo->device);
350 struct nouveau_bo_priv *nvbo = nouveau_bo(bo); 599 struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
351 struct drm_gem_close req = { bo->handle }; 600 struct drm_gem_close req = { .handle = bo->handle };
352 601
353 pthread_mutex_lock(&nvdev->lock); 602 if (nvbo->head.next) {
354 if (nvbo->name) { 603 pthread_mutex_lock(&nvdev->lock);
355 if (atomic_read(&nvbo->refcnt)) { 604 if (atomic_read(&nvbo->refcnt) == 0) {
605 DRMLISTDEL(&nvbo->head);
356 /* 606 /*
357 * bo has been revived by a race with 607 * This bo has to be closed with the lock held because
358 * nouveau_bo_prime_handle_ref, or nouveau_bo_name_ref. 608 * gem handles are not refcounted. If a shared bo is
359 * 609 * closed and re-opened in another thread a race
360 * In theory there's still a race possible with 610 * against DRM_IOCTL_GEM_OPEN or drmPrimeFDToHandle
361 * nouveau_bo_wrap, but when using this function 611 * might cause the bo to be closed accidentally while
362 * the lifetime of the handle is probably already 612 * re-importing.
363 * handled in another way. If there are races
364 * you're probably using nouveau_bo_wrap wrong.
365 */ 613 */
366 pthread_mutex_unlock(&nvdev->lock); 614 drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &req);
367 return;
368 } 615 }
369 DRMLISTDEL(&nvbo->head);
370 /*
371 * This bo has to be closed with the lock held because gem
372 * handles are not refcounted. If a shared bo is closed and
373 * re-opened in another thread a race against
374 * DRM_IOCTL_GEM_OPEN or drmPrimeFDToHandle might cause the
375 * bo to be closed accidentally while re-importing.
376 */
377 drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req);
378 pthread_mutex_unlock(&nvdev->lock); 616 pthread_mutex_unlock(&nvdev->lock);
379 } else { 617 } else {
380 DRMLISTDEL(&nvbo->head); 618 drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &req);
381 pthread_mutex_unlock(&nvdev->lock);
382 drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req);
383 } 619 }
384 if (bo->map) 620 if (bo->map)
385 drm_munmap(bo->map, bo->size); 621 drm_munmap(bo->map, bo->size);
386 free(nvbo); 622 free(nvbo);
387} 623}
388 624
389drm_public int 625int
390nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align, 626nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align,
391 uint64_t size, union nouveau_bo_config *config, 627 uint64_t size, union nouveau_bo_config *config,
392 struct nouveau_bo **pbo) 628 struct nouveau_bo **pbo)
393{ 629{
394 struct nouveau_device_priv *nvdev = nouveau_device(dev);
395 struct nouveau_bo_priv *nvbo = calloc(1, sizeof(*nvbo)); 630 struct nouveau_bo_priv *nvbo = calloc(1, sizeof(*nvbo));
396 struct nouveau_bo *bo = &nvbo->base; 631 struct nouveau_bo *bo = &nvbo->base;
397 int ret; 632 int ret;
@@ -409,18 +644,15 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align,
409 return ret; 644 return ret;
410 } 645 }
411 646
412 pthread_mutex_lock(&nvdev->lock);
413 DRMLISTADD(&nvbo->head, &nvdev->bo_list);
414 pthread_mutex_unlock(&nvdev->lock);
415
416 *pbo = bo; 647 *pbo = bo;
417 return 0; 648 return 0;
418} 649}
419 650
420static int 651static int
421nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle, 652nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle,
422 struct nouveau_bo **pbo) 653 struct nouveau_bo **pbo, int name)
423{ 654{
655 struct nouveau_drm *drm = nouveau_drm(&dev->object);
424 struct nouveau_device_priv *nvdev = nouveau_device(dev); 656 struct nouveau_device_priv *nvdev = nouveau_device(dev);
425 struct drm_nouveau_gem_info req = { .handle = handle }; 657 struct drm_nouveau_gem_info req = { .handle = handle };
426 struct nouveau_bo_priv *nvbo; 658 struct nouveau_bo_priv *nvbo;
@@ -428,13 +660,29 @@ nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle,
428 660
429 DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) { 661 DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
430 if (nvbo->base.handle == handle) { 662 if (nvbo->base.handle == handle) {
431 *pbo = NULL; 663 if (atomic_inc_return(&nvbo->refcnt) == 1) {
432 nouveau_bo_ref(&nvbo->base, pbo); 664 /*
665 * Uh oh, this bo is dead and someone else
666 * will free it, but because refcnt is
667 * now non-zero fortunately they won't
668 * call the ioctl to close the bo.
669 *
670 * Remove this bo from the list so other
671 * calls to nouveau_bo_wrap_locked will
672 * see our replacement nvbo.
673 */
674 DRMLISTDEL(&nvbo->head);
675 if (!name)
676 name = nvbo->name;
677 break;
678 }
679
680 *pbo = &nvbo->base;
433 return 0; 681 return 0;
434 } 682 }
435 } 683 }
436 684
437 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO, 685 ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_INFO,
438 &req, sizeof(req)); 686 &req, sizeof(req));
439 if (ret) 687 if (ret)
440 return ret; 688 return ret;
@@ -444,6 +692,7 @@ nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle,
444 atomic_set(&nvbo->refcnt, 1); 692 atomic_set(&nvbo->refcnt, 1);
445 nvbo->base.device = dev; 693 nvbo->base.device = dev;
446 abi16_bo_info(&nvbo->base, &req); 694 abi16_bo_info(&nvbo->base, &req);
695 nvbo->name = name;
447 DRMLISTADD(&nvbo->head, &nvdev->bo_list); 696 DRMLISTADD(&nvbo->head, &nvdev->bo_list);
448 *pbo = &nvbo->base; 697 *pbo = &nvbo->base;
449 return 0; 698 return 0;
@@ -452,22 +701,35 @@ nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle,
452 return -ENOMEM; 701 return -ENOMEM;
453} 702}
454 703
455drm_public int 704static void
705nouveau_bo_make_global(struct nouveau_bo_priv *nvbo)
706{
707 if (!nvbo->head.next) {
708 struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device);
709 pthread_mutex_lock(&nvdev->lock);
710 if (!nvbo->head.next)
711 DRMLISTADD(&nvbo->head, &nvdev->bo_list);
712 pthread_mutex_unlock(&nvdev->lock);
713 }
714}
715
716int
456nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle, 717nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
457 struct nouveau_bo **pbo) 718 struct nouveau_bo **pbo)
458{ 719{
459 struct nouveau_device_priv *nvdev = nouveau_device(dev); 720 struct nouveau_device_priv *nvdev = nouveau_device(dev);
460 int ret; 721 int ret;
461 pthread_mutex_lock(&nvdev->lock); 722 pthread_mutex_lock(&nvdev->lock);
462 ret = nouveau_bo_wrap_locked(dev, handle, pbo); 723 ret = nouveau_bo_wrap_locked(dev, handle, pbo, 0);
463 pthread_mutex_unlock(&nvdev->lock); 724 pthread_mutex_unlock(&nvdev->lock);
464 return ret; 725 return ret;
465} 726}
466 727
467drm_public int 728int
468nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name, 729nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
469 struct nouveau_bo **pbo) 730 struct nouveau_bo **pbo)
470{ 731{
732 struct nouveau_drm *drm = nouveau_drm(&dev->object);
471 struct nouveau_device_priv *nvdev = nouveau_device(dev); 733 struct nouveau_device_priv *nvdev = nouveau_device(dev);
472 struct nouveau_bo_priv *nvbo; 734 struct nouveau_bo_priv *nvbo;
473 struct drm_gem_open req = { .name = name }; 735 struct drm_gem_open req = { .name = name };
@@ -476,42 +738,45 @@ nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
476 pthread_mutex_lock(&nvdev->lock); 738 pthread_mutex_lock(&nvdev->lock);
477 DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) { 739 DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
478 if (nvbo->name == name) { 740 if (nvbo->name == name) {
479 *pbo = NULL; 741 ret = nouveau_bo_wrap_locked(dev, nvbo->base.handle,
480 nouveau_bo_ref(&nvbo->base, pbo); 742 pbo, name);
481 pthread_mutex_unlock(&nvdev->lock); 743 pthread_mutex_unlock(&nvdev->lock);
482 return 0; 744 return ret;
483 } 745 }
484 } 746 }
485 747
486 ret = drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req); 748 ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, &req);
487 if (ret == 0) { 749 if (ret == 0) {
488 ret = nouveau_bo_wrap_locked(dev, req.handle, pbo); 750 ret = nouveau_bo_wrap_locked(dev, req.handle, pbo, name);
489 nouveau_bo((*pbo))->name = name;
490 pthread_mutex_unlock(&nvdev->lock);
491 } 751 }
492 752
753 pthread_mutex_unlock(&nvdev->lock);
493 return ret; 754 return ret;
494} 755}
495 756
496drm_public int 757int
497nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name) 758nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
498{ 759{
499 struct drm_gem_flink req = { .handle = bo->handle }; 760 struct drm_gem_flink req = { .handle = bo->handle };
761 struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
500 struct nouveau_bo_priv *nvbo = nouveau_bo(bo); 762 struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
501 763
502 *name = nvbo->name; 764 *name = nvbo->name;
503 if (!*name || *name == ~0U) { 765 if (!*name) {
504 int ret = drmIoctl(bo->device->fd, DRM_IOCTL_GEM_FLINK, &req); 766 int ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, &req);
767
505 if (ret) { 768 if (ret) {
506 *name = 0; 769 *name = 0;
507 return ret; 770 return ret;
508 } 771 }
509 nvbo->name = *name = req.name; 772 nvbo->name = *name = req.name;
773
774 nouveau_bo_make_global(nvbo);
510 } 775 }
511 return 0; 776 return 0;
512} 777}
513 778
514drm_public void 779void
515nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref) 780nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref)
516{ 781{
517 struct nouveau_bo *ref = *pref; 782 struct nouveau_bo *ref = *pref;
@@ -525,10 +790,11 @@ nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref)
525 *pref = bo; 790 *pref = bo;
526} 791}
527 792
528drm_public int 793int
529nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd, 794nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
530 struct nouveau_bo **bo) 795 struct nouveau_bo **bo)
531{ 796{
797 struct nouveau_drm *drm = nouveau_drm(&dev->object);
532 struct nouveau_device_priv *nvdev = nouveau_device(dev); 798 struct nouveau_device_priv *nvdev = nouveau_device(dev);
533 int ret; 799 int ret;
534 unsigned int handle; 800 unsigned int handle;
@@ -536,42 +802,34 @@ nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
536 nouveau_bo_ref(NULL, bo); 802 nouveau_bo_ref(NULL, bo);
537 803
538 pthread_mutex_lock(&nvdev->lock); 804 pthread_mutex_lock(&nvdev->lock);
539 ret = drmPrimeFDToHandle(dev->fd, prime_fd, &handle); 805 ret = drmPrimeFDToHandle(drm->fd, prime_fd, &handle);
540 if (ret == 0) { 806 if (ret == 0) {
541 ret = nouveau_bo_wrap_locked(dev, handle, bo); 807 ret = nouveau_bo_wrap_locked(dev, handle, bo, 0);
542 if (!ret) {
543 struct nouveau_bo_priv *nvbo = nouveau_bo(*bo);
544 if (!nvbo->name) {
545 /*
546 * XXX: Force locked DRM_IOCTL_GEM_CLOSE
547 * to rule out race conditions
548 */
549 nvbo->name = ~0;
550 }
551 }
552 } 808 }
553 pthread_mutex_unlock(&nvdev->lock); 809 pthread_mutex_unlock(&nvdev->lock);
554 return ret; 810 return ret;
555} 811}
556 812
557drm_public int 813int
558nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd) 814nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd)
559{ 815{
816 struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
560 struct nouveau_bo_priv *nvbo = nouveau_bo(bo); 817 struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
561 int ret; 818 int ret;
562 819
563 ret = drmPrimeHandleToFD(bo->device->fd, nvbo->base.handle, DRM_CLOEXEC, prime_fd); 820 ret = drmPrimeHandleToFD(drm->fd, nvbo->base.handle, DRM_CLOEXEC, prime_fd);
564 if (ret) 821 if (ret)
565 return ret; 822 return ret;
566 if (!nvbo->name) 823
567 nvbo->name = ~0; 824 nouveau_bo_make_global(nvbo);
568 return 0; 825 return 0;
569} 826}
570 827
571drm_public int 828int
572nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access, 829nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
573 struct nouveau_client *client) 830 struct nouveau_client *client)
574{ 831{
832 struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
575 struct nouveau_bo_priv *nvbo = nouveau_bo(bo); 833 struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
576 struct drm_nouveau_gem_cpu_prep req; 834 struct drm_nouveau_gem_cpu_prep req;
577 struct nouveau_pushbuf *push; 835 struct nouveau_pushbuf *push;
@@ -584,8 +842,8 @@ nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
584 if (push && push->channel) 842 if (push && push->channel)
585 nouveau_pushbuf_kick(push, push->channel); 843 nouveau_pushbuf_kick(push, push->channel);
586 844
587 if (!nvbo->name && !(nvbo->access & NOUVEAU_BO_WR) && 845 if (!nvbo->head.next && !(nvbo->access & NOUVEAU_BO_WR) &&
588 !( access & NOUVEAU_BO_WR)) 846 !(access & NOUVEAU_BO_WR))
589 return 0; 847 return 0;
590 848
591 req.handle = bo->handle; 849 req.handle = bo->handle;
@@ -595,21 +853,22 @@ nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
595 if (access & NOUVEAU_BO_NOBLOCK) 853 if (access & NOUVEAU_BO_NOBLOCK)
596 req.flags |= NOUVEAU_GEM_CPU_PREP_NOWAIT; 854 req.flags |= NOUVEAU_GEM_CPU_PREP_NOWAIT;
597 855
598 ret = drmCommandWrite(bo->device->fd, DRM_NOUVEAU_GEM_CPU_PREP, 856 ret = drmCommandWrite(drm->fd, DRM_NOUVEAU_GEM_CPU_PREP,
599 &req, sizeof(req)); 857 &req, sizeof(req));
600 if (ret == 0) 858 if (ret == 0)
601 nvbo->access = 0; 859 nvbo->access = 0;
602 return ret; 860 return ret;
603} 861}
604 862
605drm_public int 863int
606nouveau_bo_map(struct nouveau_bo *bo, uint32_t access, 864nouveau_bo_map(struct nouveau_bo *bo, uint32_t access,
607 struct nouveau_client *client) 865 struct nouveau_client *client)
608{ 866{
867 struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
609 struct nouveau_bo_priv *nvbo = nouveau_bo(bo); 868 struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
610 if (bo->map == NULL) { 869 if (bo->map == NULL) {
611 bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, 870 bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
612 MAP_SHARED, bo->device->fd, nvbo->map_handle); 871 MAP_SHARED, drm->fd, nvbo->map_handle);
613 if (bo->map == MAP_FAILED) { 872 if (bo->map == MAP_FAILED) {
614 bo->map = NULL; 873 bo->map = NULL;
615 return -errno; 874 return -errno;
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index a55e2b02..335ce77d 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -4,76 +4,66 @@
4#include <stdint.h> 4#include <stdint.h>
5#include <stdbool.h> 5#include <stdbool.h>
6 6
7#define NOUVEAU_DEVICE_CLASS 0x80000000 7/* Supported class information, provided by the kernel */
8#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001 8struct nouveau_sclass {
9#define NOUVEAU_NOTIFIER_CLASS 0x80000002 9 int32_t oclass;
10#define NOUVEAU_PARENT_CLASS 0xffffffff 10 int minver;
11 int maxver;
12};
11 13
12struct nouveau_list { 14/* Client-provided array describing class versions that are desired.
13 struct nouveau_list *prev; 15 *
14 struct nouveau_list *next; 16 * These are used to match against the kernel's list of supported classes.
17 */
18struct nouveau_mclass {
19 int32_t oclass;
20 int version;
21 void *data;
15}; 22};
16 23
17struct nouveau_object { 24struct nouveau_object {
18 struct nouveau_object *parent; 25 struct nouveau_object *parent;
19 uint64_t handle; 26 uint64_t handle;
20 uint32_t oclass; 27 uint32_t oclass;
21 uint32_t length; 28 uint32_t length; /* deprecated */
22 void *data; 29 void *data; /* deprecated */
23};
24
25struct nouveau_fifo {
26 struct nouveau_object *object;
27 uint32_t channel;
28 uint32_t pushbuf;
29 uint64_t unused1[3];
30};
31
32struct nv04_fifo {
33 struct nouveau_fifo base;
34 uint32_t vram;
35 uint32_t gart;
36 uint32_t notify;
37};
38
39struct nvc0_fifo {
40 struct nouveau_fifo base;
41 uint32_t notify;
42}; 30};
43 31
44#define NVE0_FIFO_ENGINE_GR 0x00000001 32int nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
45#define NVE0_FIFO_ENGINE_VP 0x00000002 33 uint32_t oclass, void *data, uint32_t length,
46#define NVE0_FIFO_ENGINE_PPP 0x00000004 34 struct nouveau_object **);
47#define NVE0_FIFO_ENGINE_BSP 0x00000008 35void nouveau_object_del(struct nouveau_object **);
48#define NVE0_FIFO_ENGINE_CE0 0x00000010 36int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd,
49#define NVE0_FIFO_ENGINE_CE1 0x00000020 37 void *data, uint32_t size);
50#define NVE0_FIFO_ENGINE_ENC 0x00000040 38int nouveau_object_sclass_get(struct nouveau_object *,
39 struct nouveau_sclass **);
40void nouveau_object_sclass_put(struct nouveau_sclass **);
41int nouveau_object_mclass(struct nouveau_object *,
42 const struct nouveau_mclass *);
51 43
52struct nve0_fifo { 44struct nouveau_drm {
53 struct { 45 struct nouveau_object client;
54 struct nouveau_fifo base; 46 int fd;
55 uint32_t notify; 47 uint32_t version;
56 }; 48 bool nvif;
57 uint32_t engine;
58}; 49};
59 50
60struct nv04_notify { 51static inline struct nouveau_drm *
61 struct nouveau_object *object; 52nouveau_drm(struct nouveau_object *obj)
62 uint32_t offset; 53{
63 uint32_t length; 54 while (obj && obj->parent)
64}; 55 obj = obj->parent;
56 return (struct nouveau_drm *)obj;
57}
65 58
66int nouveau_object_new(struct nouveau_object *parent, uint64_t handle, 59int nouveau_drm_new(int fd, struct nouveau_drm **);
67 uint32_t oclass, void *data, uint32_t length, 60void nouveau_drm_del(struct nouveau_drm **);
68 struct nouveau_object **);
69void nouveau_object_del(struct nouveau_object **);
70void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class);
71 61
72struct nouveau_device { 62struct nouveau_device {
73 struct nouveau_object object; 63 struct nouveau_object object;
74 int fd; 64 int fd; /* deprecated */
75 uint32_t lib_version; 65 uint32_t lib_version; /* deprecated */
76 uint32_t drm_version; 66 uint32_t drm_version; /* deprecated */
77 uint32_t chipset; 67 uint32_t chipset;
78 uint64_t vram_size; 68 uint64_t vram_size;
79 uint64_t gart_size; 69 uint64_t gart_size;
@@ -81,18 +71,23 @@ struct nouveau_device {
81 uint64_t gart_limit; 71 uint64_t gart_limit;
82}; 72};
83 73
84int nouveau_device_wrap(int fd, int close, struct nouveau_device **); 74int nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
85int nouveau_device_open(const char *busid, struct nouveau_device **); 75 void *data, uint32_t size, struct nouveau_device **);
86void nouveau_device_del(struct nouveau_device **); 76void nouveau_device_del(struct nouveau_device **);
87int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value); 77
88int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value); 78int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value);
79int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value);
80
81/* deprecated */
82int nouveau_device_wrap(int fd, int close, struct nouveau_device **);
83int nouveau_device_open(const char *busid, struct nouveau_device **);
89 84
90struct nouveau_client { 85struct nouveau_client {
91 struct nouveau_device *device; 86 struct nouveau_device *device;
92 int id; 87 int id;
93}; 88};
94 89
95int nouveau_client_new(struct nouveau_device *, struct nouveau_client **); 90int nouveau_client_new(struct nouveau_device *, struct nouveau_client **);
96void nouveau_client_del(struct nouveau_client **); 91void nouveau_client_del(struct nouveau_client **);
97 92
98union nouveau_bo_config { 93union nouveau_bo_config {
@@ -127,6 +122,7 @@ union nouveau_bo_config {
127#define NOUVEAU_BO_MAP 0x80000000 122#define NOUVEAU_BO_MAP 0x80000000
128#define NOUVEAU_BO_CONTIG 0x40000000 123#define NOUVEAU_BO_CONTIG 0x40000000
129#define NOUVEAU_BO_NOSNOOP 0x20000000 124#define NOUVEAU_BO_NOSNOOP 0x20000000
125#define NOUVEAU_BO_COHERENT 0x10000000
130 126
131struct nouveau_bo { 127struct nouveau_bo {
132 struct nouveau_device *device; 128 struct nouveau_device *device;
@@ -138,22 +134,27 @@ struct nouveau_bo {
138 union nouveau_bo_config config; 134 union nouveau_bo_config config;
139}; 135};
140 136
141int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align, 137int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align,
142 uint64_t size, union nouveau_bo_config *, 138 uint64_t size, union nouveau_bo_config *,
139 struct nouveau_bo **);
140int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle,
143 struct nouveau_bo **); 141 struct nouveau_bo **);
144int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle, 142int nouveau_bo_name_ref(struct nouveau_device *v, uint32_t name,
145 struct nouveau_bo **); 143 struct nouveau_bo **);
146int nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name, 144int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name);
147 struct nouveau_bo **);
148int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name);
149void nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **); 145void nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
150int nouveau_bo_map(struct nouveau_bo *, uint32_t access, 146int nouveau_bo_map(struct nouveau_bo *, uint32_t access,
147 struct nouveau_client *);
148int nouveau_bo_wait(struct nouveau_bo *, uint32_t access,
151 struct nouveau_client *); 149 struct nouveau_client *);
152int nouveau_bo_wait(struct nouveau_bo *, uint32_t access, 150int nouveau_bo_prime_handle_ref(struct nouveau_device *, int prime_fd,
153 struct nouveau_client *); 151 struct nouveau_bo **);
154int nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd, 152int nouveau_bo_set_prime(struct nouveau_bo *, int *prime_fd);
155 struct nouveau_bo **); 153
156int nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd); 154struct nouveau_list {
155 struct nouveau_list *prev;
156 struct nouveau_list *next;
157};
157 158
158struct nouveau_bufref { 159struct nouveau_bufref {
159 struct nouveau_list thead; 160 struct nouveau_list thead;
@@ -175,8 +176,8 @@ struct nouveau_bufctx {
175 int relocs; 176 int relocs;
176}; 177};
177 178
178int nouveau_bufctx_new(struct nouveau_client *, int bins, 179int nouveau_bufctx_new(struct nouveau_client *, int bins,
179 struct nouveau_bufctx **); 180 struct nouveau_bufctx **);
180void nouveau_bufctx_del(struct nouveau_bufctx **); 181void nouveau_bufctx_del(struct nouveau_bufctx **);
181struct nouveau_bufref * 182struct nouveau_bufref *
182nouveau_bufctx_refn(struct nouveau_bufctx *, int bin, 183nouveau_bufctx_refn(struct nouveau_bufctx *, int bin,
@@ -205,16 +206,16 @@ struct nouveau_pushbuf_refn {
205 uint32_t flags; 206 uint32_t flags;
206}; 207};
207 208
208int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *channel, 209int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *chan,
209 int nr, uint32_t size, bool immediate, 210 int nr, uint32_t size, bool immediate,
210 struct nouveau_pushbuf **); 211 struct nouveau_pushbuf **);
211void nouveau_pushbuf_del(struct nouveau_pushbuf **); 212void nouveau_pushbuf_del(struct nouveau_pushbuf **);
212int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords, 213int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords,
213 uint32_t relocs, uint32_t pushes); 214 uint32_t relocs, uint32_t pushes);
214void nouveau_pushbuf_data(struct nouveau_pushbuf *, struct nouveau_bo *, 215void nouveau_pushbuf_data(struct nouveau_pushbuf *, struct nouveau_bo *,
215 uint64_t offset, uint64_t length); 216 uint64_t offset, uint64_t length);
216int nouveau_pushbuf_refn(struct nouveau_pushbuf *, 217int nouveau_pushbuf_refn(struct nouveau_pushbuf *,
217 struct nouveau_pushbuf_refn *, int nr); 218 struct nouveau_pushbuf_refn *, int nr);
218/* Emits a reloc into the push buffer at the current position, you *must* 219/* Emits a reloc into the push buffer at the current position, you *must*
219 * have previously added the referenced buffer to a buffer context, and 220 * have previously added the referenced buffer to a buffer context, and
220 * validated it against the current push buffer. 221 * validated it against the current push buffer.
@@ -222,10 +223,54 @@ int nouveau_pushbuf_refn(struct nouveau_pushbuf *,
222void nouveau_pushbuf_reloc(struct nouveau_pushbuf *, struct nouveau_bo *, 223void nouveau_pushbuf_reloc(struct nouveau_pushbuf *, struct nouveau_bo *,
223 uint32_t data, uint32_t flags, 224 uint32_t data, uint32_t flags,
224 uint32_t vor, uint32_t tor); 225 uint32_t vor, uint32_t tor);
225int nouveau_pushbuf_validate(struct nouveau_pushbuf *); 226int nouveau_pushbuf_validate(struct nouveau_pushbuf *);
226uint32_t nouveau_pushbuf_refd(struct nouveau_pushbuf *, struct nouveau_bo *); 227uint32_t nouveau_pushbuf_refd(struct nouveau_pushbuf *, struct nouveau_bo *);
227int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *channel); 228int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *chan);
228struct nouveau_bufctx * 229struct nouveau_bufctx *
229nouveau_pushbuf_bufctx(struct nouveau_pushbuf *, struct nouveau_bufctx *); 230nouveau_pushbuf_bufctx(struct nouveau_pushbuf *, struct nouveau_bufctx *);
230 231
232#define NOUVEAU_DEVICE_CLASS 0x80000000
233#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001
234#define NOUVEAU_NOTIFIER_CLASS 0x80000002
235
236struct nouveau_fifo {
237 struct nouveau_object *object;
238 uint32_t channel;
239 uint32_t pushbuf;
240 uint64_t unused1[3];
241};
242
243struct nv04_fifo {
244 struct nouveau_fifo base;
245 uint32_t vram;
246 uint32_t gart;
247 uint32_t notify;
248};
249
250struct nvc0_fifo {
251 struct nouveau_fifo base;
252 uint32_t notify;
253};
254
255#define NVE0_FIFO_ENGINE_GR 0x00000001
256#define NVE0_FIFO_ENGINE_VP 0x00000002
257#define NVE0_FIFO_ENGINE_PPP 0x00000004
258#define NVE0_FIFO_ENGINE_BSP 0x00000008
259#define NVE0_FIFO_ENGINE_CE0 0x00000010
260#define NVE0_FIFO_ENGINE_CE1 0x00000020
261#define NVE0_FIFO_ENGINE_ENC 0x00000040
262
263struct nve0_fifo {
264 struct {
265 struct nouveau_fifo base;
266 uint32_t notify;
267 };
268 uint32_t engine;
269};
270
271struct nv04_notify {
272 struct nouveau_object *object;
273 uint32_t offset;
274 uint32_t length;
275};
231#endif 276#endif
diff --git a/nouveau/nvif/cl0080.h b/nouveau/nvif/cl0080.h
new file mode 100644
index 00000000..331620a5
--- /dev/null
+++ b/nouveau/nvif/cl0080.h
@@ -0,0 +1,45 @@
1#ifndef __NVIF_CL0080_H__
2#define __NVIF_CL0080_H__
3
4struct nv_device_v0 {
5 __u8 version;
6 __u8 pad01[7];
7 __u64 device; /* device identifier, ~0 for client default */
8};
9
10#define NV_DEVICE_V0_INFO 0x00
11#define NV_DEVICE_V0_TIME 0x01
12
13struct nv_device_info_v0 {
14 __u8 version;
15#define NV_DEVICE_INFO_V0_IGP 0x00
16#define NV_DEVICE_INFO_V0_PCI 0x01
17#define NV_DEVICE_INFO_V0_AGP 0x02
18#define NV_DEVICE_INFO_V0_PCIE 0x03
19#define NV_DEVICE_INFO_V0_SOC 0x04
20 __u8 platform;
21 __u16 chipset; /* from NV_PMC_BOOT_0 */
22 __u8 revision; /* from NV_PMC_BOOT_0 */
23#define NV_DEVICE_INFO_V0_TNT 0x01
24#define NV_DEVICE_INFO_V0_CELSIUS 0x02
25#define NV_DEVICE_INFO_V0_KELVIN 0x03
26#define NV_DEVICE_INFO_V0_RANKINE 0x04
27#define NV_DEVICE_INFO_V0_CURIE 0x05
28#define NV_DEVICE_INFO_V0_TESLA 0x06
29#define NV_DEVICE_INFO_V0_FERMI 0x07
30#define NV_DEVICE_INFO_V0_KEPLER 0x08
31#define NV_DEVICE_INFO_V0_MAXWELL 0x09
32 __u8 family;
33 __u8 pad06[2];
34 __u64 ram_size;
35 __u64 ram_user;
36 char chip[16];
37 char name[64];
38};
39
40struct nv_device_time_v0 {
41 __u8 version;
42 __u8 pad01[7];
43 __u64 time;
44};
45#endif
diff --git a/nouveau/nvif/cl9097.h b/nouveau/nvif/cl9097.h
new file mode 100644
index 00000000..4057676d
--- /dev/null
+++ b/nouveau/nvif/cl9097.h
@@ -0,0 +1,44 @@
1#ifndef __NVIF_CL9097_H__
2#define __NVIF_CL9097_H__
3
4#define FERMI_A_ZBC_COLOR 0x00
5#define FERMI_A_ZBC_DEPTH 0x01
6
7struct fermi_a_zbc_color_v0 {
8 __u8 version;
9#define FERMI_A_ZBC_COLOR_V0_FMT_ZERO 0x01
10#define FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE 0x02
11#define FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32 0x04
12#define FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16 0x08
13#define FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16 0x0c
14#define FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16 0x10
15#define FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16 0x14
16#define FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16 0x16
17#define FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8 0x18
18#define FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8 0x1c
19#define FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10 0x20
20#define FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10 0x24
21#define FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8 0x28
22#define FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8 0x2c
23#define FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8 0x30
24#define FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8 0x34
25#define FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8 0x38
26#define FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10 0x3c
27#define FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11 0x40
28 __u8 format;
29 __u8 index;
30 __u8 pad03[5];
31 __u32 ds[4];
32 __u32 l2[4];
33};
34
35struct fermi_a_zbc_depth_v0 {
36 __u8 version;
37#define FERMI_A_ZBC_DEPTH_V0_FMT_FP32 0x01
38 __u8 format;
39 __u8 index;
40 __u8 pad03[5];
41 __u32 ds;
42 __u32 l2;
43};
44#endif
diff --git a/nouveau/nvif/class.h b/nouveau/nvif/class.h
new file mode 100644
index 00000000..4179cd65
--- /dev/null
+++ b/nouveau/nvif/class.h
@@ -0,0 +1,141 @@
1#ifndef __NVIF_CLASS_H__
2#define __NVIF_CLASS_H__
3
4/* these class numbers are made up by us, and not nvidia-assigned */
5#define NVIF_CLASS_CONTROL /* if0001.h */ -1
6#define NVIF_CLASS_PERFMON /* if0002.h */ -2
7#define NVIF_CLASS_PERFDOM /* if0003.h */ -3
8#define NVIF_CLASS_SW_NV04 /* if0004.h */ -4
9#define NVIF_CLASS_SW_NV10 /* if0005.h */ -5
10#define NVIF_CLASS_SW_NV50 /* if0005.h */ -6
11#define NVIF_CLASS_SW_GF100 /* if0005.h */ -7
12
13/* the below match nvidia-assigned (either in hw, or sw) class numbers */
14#define NV_DEVICE /* cl0080.h */ 0x00000080
15
16#define NV_DMA_FROM_MEMORY /* cl0002.h */ 0x00000002
17#define NV_DMA_TO_MEMORY /* cl0002.h */ 0x00000003
18#define NV_DMA_IN_MEMORY /* cl0002.h */ 0x0000003d
19
20#define FERMI_TWOD_A 0x0000902d
21
22#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x00009039
23
24#define KEPLER_INLINE_TO_MEMORY_A 0x0000a040
25#define KEPLER_INLINE_TO_MEMORY_B 0x0000a140
26
27#define NV04_DISP /* cl0046.h */ 0x00000046
28
29#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
30#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
31#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
32#define NV40_CHANNEL_DMA /* cl506b.h */ 0x0000406e
33#define NV50_CHANNEL_DMA /* cl506e.h */ 0x0000506e
34#define G82_CHANNEL_DMA /* cl826e.h */ 0x0000826e
35
36#define NV50_CHANNEL_GPFIFO /* cl506f.h */ 0x0000506f
37#define G82_CHANNEL_GPFIFO /* cl826f.h */ 0x0000826f
38#define FERMI_CHANNEL_GPFIFO /* cl906f.h */ 0x0000906f
39#define KEPLER_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000a06f
40#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f
41
42#define NV50_DISP /* cl5070.h */ 0x00005070
43#define G82_DISP /* cl5070.h */ 0x00008270
44#define GT200_DISP /* cl5070.h */ 0x00008370
45#define GT214_DISP /* cl5070.h */ 0x00008570
46#define GT206_DISP /* cl5070.h */ 0x00008870
47#define GF110_DISP /* cl5070.h */ 0x00009070
48#define GK104_DISP /* cl5070.h */ 0x00009170
49#define GK110_DISP /* cl5070.h */ 0x00009270
50#define GM107_DISP /* cl5070.h */ 0x00009470
51#define GM204_DISP /* cl5070.h */ 0x00009570
52
53#define NV31_MPEG 0x00003174
54#define G82_MPEG 0x00008274
55
56#define NV74_VP2 0x00007476
57
58#define NV50_DISP_CURSOR /* cl507a.h */ 0x0000507a
59#define G82_DISP_CURSOR /* cl507a.h */ 0x0000827a
60#define GT214_DISP_CURSOR /* cl507a.h */ 0x0000857a
61#define GF110_DISP_CURSOR /* cl507a.h */ 0x0000907a
62#define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a
63
64#define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b
65#define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b
66#define GT214_DISP_OVERLAY /* cl507b.h */ 0x0000857b
67#define GF110_DISP_OVERLAY /* cl507b.h */ 0x0000907b
68#define GK104_DISP_OVERLAY /* cl507b.h */ 0x0000917b
69
70#define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c
71#define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c
72#define GT200_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000837c
73#define GT214_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000857c
74#define GF110_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000907c
75#define GK104_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000917c
76#define GK110_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000927c
77
78#define NV50_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000507d
79#define G82_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000827d
80#define GT200_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000837d
81#define GT214_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000857d
82#define GT206_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000887d
83#define GF110_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000907d
84#define GK104_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000917d
85#define GK110_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000927d
86#define GM107_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000947d
87#define GM204_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000957d
88
89#define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e
90#define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e
91#define GT200_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000837e
92#define GT214_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000857e
93#define GF110_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000907e
94#define GK104_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000917e
95
96#define FERMI_A /* cl9097.h */ 0x00009097
97#define FERMI_B /* cl9097.h */ 0x00009197
98#define FERMI_C /* cl9097.h */ 0x00009297
99
100#define KEPLER_A /* cl9097.h */ 0x0000a097
101#define KEPLER_B /* cl9097.h */ 0x0000a197
102#define KEPLER_C /* cl9097.h */ 0x0000a297
103
104#define MAXWELL_A /* cl9097.h */ 0x0000b097
105#define MAXWELL_B /* cl9097.h */ 0x0000b197
106
107#define NV74_BSP 0x000074b0
108
109#define GT212_MSVLD 0x000085b1
110#define IGT21A_MSVLD 0x000086b1
111#define G98_MSVLD 0x000088b1
112#define GF100_MSVLD 0x000090b1
113#define GK104_MSVLD 0x000095b1
114
115#define GT212_MSPDEC 0x000085b2
116#define G98_MSPDEC 0x000088b2
117#define GF100_MSPDEC 0x000090b2
118#define GK104_MSPDEC 0x000095b2
119
120#define GT212_MSPPP 0x000085b3
121#define G98_MSPPP 0x000088b3
122#define GF100_MSPPP 0x000090b3
123
124#define G98_SEC 0x000088b4
125
126#define GT212_DMA 0x000085b5
127#define FERMI_DMA 0x000090b5
128#define KEPLER_DMA_COPY_A 0x0000a0b5
129#define MAXWELL_DMA_COPY_A 0x0000b0b5
130
131#define FERMI_DECOMPRESS 0x000090b8
132
133#define FERMI_COMPUTE_A 0x000090c0
134#define FERMI_COMPUTE_B 0x000091c0
135#define KEPLER_COMPUTE_A 0x0000a0c0
136#define KEPLER_COMPUTE_B 0x0000a1c0
137#define MAXWELL_COMPUTE_A 0x0000b0c0
138#define MAXWELL_COMPUTE_B 0x0000b1c0
139
140#define NV74_CIPHER 0x000074c1
141#endif
diff --git a/nouveau/nvif/if0002.h b/nouveau/nvif/if0002.h
new file mode 100644
index 00000000..c04c91d0
--- /dev/null
+++ b/nouveau/nvif/if0002.h
@@ -0,0 +1,38 @@
1#ifndef __NVIF_IF0002_H__
2#define __NVIF_IF0002_H__
3
4#define NVIF_PERFMON_V0_QUERY_DOMAIN 0x00
5#define NVIF_PERFMON_V0_QUERY_SIGNAL 0x01
6#define NVIF_PERFMON_V0_QUERY_SOURCE 0x02
7
8struct nvif_perfmon_query_domain_v0 {
9 __u8 version;
10 __u8 id;
11 __u8 counter_nr;
12 __u8 iter;
13 __u16 signal_nr;
14 __u8 pad05[2];
15 char name[64];
16};
17
18struct nvif_perfmon_query_signal_v0 {
19 __u8 version;
20 __u8 domain;
21 __u16 iter;
22 __u8 signal;
23 __u8 source_nr;
24 __u8 pad05[2];
25 char name[64];
26};
27
28struct nvif_perfmon_query_source_v0 {
29 __u8 version;
30 __u8 domain;
31 __u8 signal;
32 __u8 iter;
33 __u8 pad04[4];
34 __u32 source;
35 __u32 mask;
36 char name[64];
37};
38#endif
diff --git a/nouveau/nvif/if0003.h b/nouveau/nvif/if0003.h
new file mode 100644
index 00000000..0cd03efb
--- /dev/null
+++ b/nouveau/nvif/if0003.h
@@ -0,0 +1,33 @@
1#ifndef __NVIF_IF0003_H__
2#define __NVIF_IF0003_H__
3
4struct nvif_perfdom_v0 {
5 __u8 version;
6 __u8 domain;
7 __u8 mode;
8 __u8 pad03[1];
9 struct {
10 __u8 signal[4];
11 __u64 source[4][8];
12 __u16 logic_op;
13 } ctr[4];
14};
15
16#define NVIF_PERFDOM_V0_INIT 0x00
17#define NVIF_PERFDOM_V0_SAMPLE 0x01
18#define NVIF_PERFDOM_V0_READ 0x02
19
20struct nvif_perfdom_init {
21};
22
23struct nvif_perfdom_sample {
24};
25
26struct nvif_perfdom_read_v0 {
27 __u8 version;
28 __u8 pad01[7];
29 __u32 ctr[4];
30 __u32 clk;
31 __u8 pad04[4];
32};
33#endif
diff --git a/nouveau/nvif/ioctl.h b/nouveau/nvif/ioctl.h
new file mode 100644
index 00000000..c5f5eb83
--- /dev/null
+++ b/nouveau/nvif/ioctl.h
@@ -0,0 +1,132 @@
1#ifndef __NVIF_IOCTL_H__
2#define __NVIF_IOCTL_H__
3
4#define NVIF_VERSION_LATEST 0x0000000000000000ULL
5
6struct nvif_ioctl_v0 {
7 __u8 version;
8#define NVIF_IOCTL_V0_NOP 0x00
9#define NVIF_IOCTL_V0_SCLASS 0x01
10#define NVIF_IOCTL_V0_NEW 0x02
11#define NVIF_IOCTL_V0_DEL 0x03
12#define NVIF_IOCTL_V0_MTHD 0x04
13#define NVIF_IOCTL_V0_RD 0x05
14#define NVIF_IOCTL_V0_WR 0x06
15#define NVIF_IOCTL_V0_MAP 0x07
16#define NVIF_IOCTL_V0_UNMAP 0x08
17#define NVIF_IOCTL_V0_NTFY_NEW 0x09
18#define NVIF_IOCTL_V0_NTFY_DEL 0x0a
19#define NVIF_IOCTL_V0_NTFY_GET 0x0b
20#define NVIF_IOCTL_V0_NTFY_PUT 0x0c
21 __u8 type;
22 __u8 pad02[4];
23#define NVIF_IOCTL_V0_OWNER_NVIF 0x00
24#define NVIF_IOCTL_V0_OWNER_ANY 0xff
25 __u8 owner;
26#define NVIF_IOCTL_V0_ROUTE_NVIF 0x00
27#define NVIF_IOCTL_V0_ROUTE_HIDDEN 0xff
28 __u8 route;
29 __u64 token;
30 __u64 object;
31 __u8 data[]; /* ioctl data (below) */
32};
33
34struct nvif_ioctl_nop_v0 {
35 __u64 version;
36};
37
38struct nvif_ioctl_sclass_v0 {
39 /* nvif_ioctl ... */
40 __u8 version;
41 __u8 count;
42 __u8 pad02[6];
43 struct nvif_ioctl_sclass_oclass_v0 {
44 __s32 oclass;
45 __s16 minver;
46 __s16 maxver;
47 } oclass[];
48};
49
50struct nvif_ioctl_new_v0 {
51 /* nvif_ioctl ... */
52 __u8 version;
53 __u8 pad01[6];
54 __u8 route;
55 __u64 token;
56 __u64 object;
57 __u32 handle;
58 __s32 oclass;
59 __u8 data[]; /* class data (class.h) */
60};
61
62struct nvif_ioctl_del {
63};
64
65struct nvif_ioctl_rd_v0 {
66 /* nvif_ioctl ... */
67 __u8 version;
68 __u8 size;
69 __u8 pad02[2];
70 __u32 data;
71 __u64 addr;
72};
73
74struct nvif_ioctl_wr_v0 {
75 /* nvif_ioctl ... */
76 __u8 version;
77 __u8 size;
78 __u8 pad02[2];
79 __u32 data;
80 __u64 addr;
81};
82
83struct nvif_ioctl_map_v0 {
84 /* nvif_ioctl ... */
85 __u8 version;
86 __u8 pad01[3];
87 __u32 length;
88 __u64 handle;
89};
90
91struct nvif_ioctl_unmap {
92};
93
94struct nvif_ioctl_ntfy_new_v0 {
95 /* nvif_ioctl ... */
96 __u8 version;
97 __u8 event;
98 __u8 index;
99 __u8 pad03[5];
100 __u8 data[]; /* event request data (event.h) */
101};
102
103struct nvif_ioctl_ntfy_del_v0 {
104 /* nvif_ioctl ... */
105 __u8 version;
106 __u8 index;
107 __u8 pad02[6];
108};
109
110struct nvif_ioctl_ntfy_get_v0 {
111 /* nvif_ioctl ... */
112 __u8 version;
113 __u8 index;
114 __u8 pad02[6];
115};
116
117struct nvif_ioctl_ntfy_put_v0 {
118 /* nvif_ioctl ... */
119 __u8 version;
120 __u8 index;
121 __u8 pad02[6];
122};
123
124struct nvif_ioctl_mthd_v0 {
125 /* nvif_ioctl ... */
126 __u8 version;
127 __u8 method;
128 __u8 pad02[6];
129 __u8 data[]; /* method data (class.h) */
130};
131
132#endif
diff --git a/nouveau/nvif/unpack.h b/nouveau/nvif/unpack.h
new file mode 100644
index 00000000..751bcf49
--- /dev/null
+++ b/nouveau/nvif/unpack.h
@@ -0,0 +1,28 @@
1#ifndef __NVIF_UNPACK_H__
2#define __NVIF_UNPACK_H__
3
4#define nvif_unvers(r,d,s,m) ({ \
5 void **_data = (d); __u32 *_size = (s); int _ret = (r); \
6 if (_ret == -ENOSYS && *_size == sizeof(m)) { \
7 *_data = NULL; \
8 *_size = _ret = 0; \
9 } \
10 _ret; \
11})
12
13#define nvif_unpack(r,d,s,m,vl,vh,x) ({ \
14 void **_data = (d); __u32 *_size = (s); \
15 int _ret = (r), _vl = (vl), _vh = (vh); \
16 if (_ret == -ENOSYS && *_size >= sizeof(m) && \
17 (m).version >= _vl && (m).version <= _vh) { \
18 *_data = (__u8 *)*_data + sizeof(m); \
19 *_size = *_size - sizeof(m); \
20 if (_ret = 0, !(x)) { \
21 _ret = *_size ? -E2BIG : 0; \
22 *_data = NULL; \
23 *_size = 0; \
24 } \
25 } \
26 _ret; \
27})
28#endif
diff --git a/nouveau/private.h b/nouveau/private.h
index bf9db042..83060f96 100644
--- a/nouveau/private.h
+++ b/nouveau/private.h
@@ -1,7 +1,7 @@
1#ifndef __NOUVEAU_LIBDRM_PRIVATE_H__ 1#ifndef __NOUVEAU_LIBDRM_PRIVATE_H__
2#define __NOUVEAU_LIBDRM_PRIVATE_H__ 2#define __NOUVEAU_LIBDRM_PRIVATE_H__
3 3
4#include <libdrm.h> 4#include <libdrm_macros.h>
5#include <xf86drm.h> 5#include <xf86drm.h>
6#include <xf86atomic.h> 6#include <xf86atomic.h>
7#include <pthread.h> 7#include <pthread.h>
@@ -10,7 +10,7 @@
10#include "nouveau.h" 10#include "nouveau.h"
11 11
12#ifdef DEBUG 12#ifdef DEBUG
13uint32_t nouveau_debug; 13drm_private uint32_t nouveau_debug;
14#define dbg_on(lvl) (nouveau_debug & (1 << lvl)) 14#define dbg_on(lvl) (nouveau_debug & (1 << lvl))
15#define dbg(lvl, fmt, args...) do { \ 15#define dbg(lvl, fmt, args...) do { \
16 if (dbg_on((lvl))) \ 16 if (dbg_on((lvl))) \
@@ -114,13 +114,11 @@ int
114nouveau_device_open_existing(struct nouveau_device **, int, int, drm_context_t); 114nouveau_device_open_existing(struct nouveau_device **, int, int, drm_context_t);
115 115
116/* abi16.c */ 116/* abi16.c */
117int abi16_chan_nv04(struct nouveau_object *); 117drm_private bool abi16_object(struct nouveau_object *, int (**)(struct nouveau_object *));
118int abi16_chan_nvc0(struct nouveau_object *); 118drm_private void abi16_delete(struct nouveau_object *);
119int abi16_chan_nve0(struct nouveau_object *); 119drm_private int abi16_sclass(struct nouveau_object *, struct nouveau_sclass **);
120int abi16_engobj(struct nouveau_object *); 120drm_private void abi16_bo_info(struct nouveau_bo *, struct drm_nouveau_gem_info *);
121int abi16_ntfy(struct nouveau_object *); 121drm_private int abi16_bo_init(struct nouveau_bo *, uint32_t alignment,
122void abi16_bo_info(struct nouveau_bo *, struct drm_nouveau_gem_info *); 122 union nouveau_bo_config *);
123int abi16_bo_init(struct nouveau_bo *, uint32_t alignment,
124 union nouveau_bo_config *);
125 123
126#endif 124#endif
diff --git a/nouveau/pushbuf.c b/nouveau/pushbuf.c
index 6e703a44..035e3019 100644
--- a/nouveau/pushbuf.c
+++ b/nouveau/pushbuf.c
@@ -234,6 +234,8 @@ pushbuf_krel(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
234 bkref = cli_kref_get(push->client, bo); 234 bkref = cli_kref_get(push->client, bo);
235 krel = &krec->reloc[krec->nr_reloc++]; 235 krel = &krec->reloc[krec->nr_reloc++];
236 236
237 assert(pkref);
238 assert(bkref);
237 krel->reloc_bo_index = pkref - krec->buffer; 239 krel->reloc_bo_index = pkref - krec->buffer;
238 krel->reloc_bo_offset = (push->cur - nvpb->ptr) * 4; 240 krel->reloc_bo_offset = (push->cur - nvpb->ptr) * 4;
239 krel->bo_index = bkref - krec->buffer; 241 krel->bo_index = bkref - krec->buffer;
@@ -310,6 +312,7 @@ pushbuf_submit(struct nouveau_pushbuf *push, struct nouveau_object *chan)
310 struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(push); 312 struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(push);
311 struct nouveau_pushbuf_krec *krec = nvpb->list; 313 struct nouveau_pushbuf_krec *krec = nvpb->list;
312 struct nouveau_device *dev = push->client->device; 314 struct nouveau_device *dev = push->client->device;
315 struct nouveau_drm *drm = nouveau_drm(&dev->object);
313 struct drm_nouveau_gem_pushbuf_bo_presumed *info; 316 struct drm_nouveau_gem_pushbuf_bo_presumed *info;
314 struct drm_nouveau_gem_pushbuf_bo *kref; 317 struct drm_nouveau_gem_pushbuf_bo *kref;
315 struct drm_nouveau_gem_pushbuf req; 318 struct drm_nouveau_gem_pushbuf req;
@@ -343,7 +346,7 @@ pushbuf_submit(struct nouveau_pushbuf *push, struct nouveau_object *chan)
343 pushbuf_dump(krec, krec_id++, fifo->channel); 346 pushbuf_dump(krec, krec_id++, fifo->channel);
344 347
345#ifndef SIMULATE 348#ifndef SIMULATE
346 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_PUSHBUF, 349 ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_PUSHBUF,
347 &req, sizeof(req)); 350 &req, sizeof(req));
348 nvpb->suffix0 = req.suffix0; 351 nvpb->suffix0 = req.suffix0;
349 nvpb->suffix1 = req.suffix1; 352 nvpb->suffix1 = req.suffix1;
@@ -529,12 +532,12 @@ pushbuf_validate(struct nouveau_pushbuf *push, bool retry)
529 return ret; 532 return ret;
530} 533}
531 534
532drm_public int 535int
533nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan, 536nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan,
534 int nr, uint32_t size, bool immediate, 537 int nr, uint32_t size, bool immediate,
535 struct nouveau_pushbuf **ppush) 538 struct nouveau_pushbuf **ppush)
536{ 539{
537 struct nouveau_device *dev = client->device; 540 struct nouveau_drm *drm = nouveau_drm(&client->device->object);
538 struct nouveau_fifo *fifo = chan->data; 541 struct nouveau_fifo *fifo = chan->data;
539 struct nouveau_pushbuf_priv *nvpb; 542 struct nouveau_pushbuf_priv *nvpb;
540 struct nouveau_pushbuf *push; 543 struct nouveau_pushbuf *push;
@@ -549,7 +552,7 @@ nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan,
549 */ 552 */
550 req.channel = fifo->channel; 553 req.channel = fifo->channel;
551 req.nr_push = 0; 554 req.nr_push = 0;
552 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_PUSHBUF, 555 ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_PUSHBUF,
553 &req, sizeof(req)); 556 &req, sizeof(req));
554 if (ret) 557 if (ret)
555 return ret; 558 return ret;
@@ -600,7 +603,7 @@ nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan,
600 return 0; 603 return 0;
601} 604}
602 605
603drm_public void 606void
604nouveau_pushbuf_del(struct nouveau_pushbuf **ppush) 607nouveau_pushbuf_del(struct nouveau_pushbuf **ppush)
605{ 608{
606 struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(*ppush); 609 struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(*ppush);
@@ -626,7 +629,7 @@ nouveau_pushbuf_del(struct nouveau_pushbuf **ppush)
626 *ppush = NULL; 629 *ppush = NULL;
627} 630}
628 631
629drm_public struct nouveau_bufctx * 632struct nouveau_bufctx *
630nouveau_pushbuf_bufctx(struct nouveau_pushbuf *push, struct nouveau_bufctx *ctx) 633nouveau_pushbuf_bufctx(struct nouveau_pushbuf *push, struct nouveau_bufctx *ctx)
631{ 634{
632 struct nouveau_bufctx *prev = push->bufctx; 635 struct nouveau_bufctx *prev = push->bufctx;
@@ -634,7 +637,7 @@ nouveau_pushbuf_bufctx(struct nouveau_pushbuf *push, struct nouveau_bufctx *ctx)
634 return prev; 637 return prev;
635} 638}
636 639
637drm_public int 640int
638nouveau_pushbuf_space(struct nouveau_pushbuf *push, 641nouveau_pushbuf_space(struct nouveau_pushbuf *push,
639 uint32_t dwords, uint32_t relocs, uint32_t pushes) 642 uint32_t dwords, uint32_t relocs, uint32_t pushes)
640{ 643{
@@ -698,7 +701,7 @@ nouveau_pushbuf_space(struct nouveau_pushbuf *push,
698 return flushed ? pushbuf_validate(push, false) : 0; 701 return flushed ? pushbuf_validate(push, false) : 0;
699} 702}
700 703
701drm_public void 704void
702nouveau_pushbuf_data(struct nouveau_pushbuf *push, struct nouveau_bo *bo, 705nouveau_pushbuf_data(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
703 uint64_t offset, uint64_t length) 706 uint64_t offset, uint64_t length)
704{ 707{
@@ -721,6 +724,7 @@ nouveau_pushbuf_data(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
721 724
722 if (bo) { 725 if (bo) {
723 kref = cli_kref_get(push->client, bo); 726 kref = cli_kref_get(push->client, bo);
727 assert(kref);
724 kpsh = &krec->push[krec->nr_push++]; 728 kpsh = &krec->push[krec->nr_push++];
725 kpsh->bo_index = kref - krec->buffer; 729 kpsh->bo_index = kref - krec->buffer;
726 kpsh->offset = offset; 730 kpsh->offset = offset;
@@ -728,14 +732,14 @@ nouveau_pushbuf_data(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
728 } 732 }
729} 733}
730 734
731drm_public int 735int
732nouveau_pushbuf_refn(struct nouveau_pushbuf *push, 736nouveau_pushbuf_refn(struct nouveau_pushbuf *push,
733 struct nouveau_pushbuf_refn *refs, int nr) 737 struct nouveau_pushbuf_refn *refs, int nr)
734{ 738{
735 return pushbuf_refn(push, true, refs, nr); 739 return pushbuf_refn(push, true, refs, nr);
736} 740}
737 741
738drm_public void 742void
739nouveau_pushbuf_reloc(struct nouveau_pushbuf *push, struct nouveau_bo *bo, 743nouveau_pushbuf_reloc(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
740 uint32_t data, uint32_t flags, uint32_t vor, uint32_t tor) 744 uint32_t data, uint32_t flags, uint32_t vor, uint32_t tor)
741{ 745{
@@ -743,13 +747,13 @@ nouveau_pushbuf_reloc(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
743 push->cur++; 747 push->cur++;
744} 748}
745 749
746drm_public int 750int
747nouveau_pushbuf_validate(struct nouveau_pushbuf *push) 751nouveau_pushbuf_validate(struct nouveau_pushbuf *push)
748{ 752{
749 return pushbuf_validate(push, true); 753 return pushbuf_validate(push, true);
750} 754}
751 755
752drm_public uint32_t 756uint32_t
753nouveau_pushbuf_refd(struct nouveau_pushbuf *push, struct nouveau_bo *bo) 757nouveau_pushbuf_refd(struct nouveau_pushbuf *push, struct nouveau_bo *bo)
754{ 758{
755 struct drm_nouveau_gem_pushbuf_bo *kref; 759 struct drm_nouveau_gem_pushbuf_bo *kref;
@@ -757,6 +761,7 @@ nouveau_pushbuf_refd(struct nouveau_pushbuf *push, struct nouveau_bo *bo)
757 761
758 if (cli_push_get(push->client, bo) == push) { 762 if (cli_push_get(push->client, bo) == push) {
759 kref = cli_kref_get(push->client, bo); 763 kref = cli_kref_get(push->client, bo);
764 assert(kref);
760 if (kref->read_domains) 765 if (kref->read_domains)
761 flags |= NOUVEAU_BO_RD; 766 flags |= NOUVEAU_BO_RD;
762 if (kref->write_domains) 767 if (kref->write_domains)
@@ -766,7 +771,7 @@ nouveau_pushbuf_refd(struct nouveau_pushbuf *push, struct nouveau_bo *bo)
766 return flags; 771 return flags;
767} 772}
768 773
769drm_public int 774int
770nouveau_pushbuf_kick(struct nouveau_pushbuf *push, struct nouveau_object *chan) 775nouveau_pushbuf_kick(struct nouveau_pushbuf *push, struct nouveau_object *chan)
771{ 776{
772 if (!push->channel) 777 if (!push->channel)
diff --git a/omap/Makefile.am b/omap/Makefile.am
index 0778bdde..599bb9de 100644
--- a/omap/Makefile.am
+++ b/omap/Makefile.am
@@ -1,8 +1,6 @@
1AM_CFLAGS = \ 1AM_CFLAGS = \
2 $(WARN_CFLAGS) \ 2 $(WARN_CFLAGS) \
3 $(VISIBILITY_CFLAGS) \
4 -I$(top_srcdir) \ 3 -I$(top_srcdir) \
5 -I$(top_srcdir)/omap \
6 $(PTHREADSTUBS_CFLAGS) \ 4 $(PTHREADSTUBS_CFLAGS) \
7 -I$(top_srcdir)/include/drm 5 -I$(top_srcdir)/include/drm
8 6
@@ -21,3 +19,6 @@ libdrm_omapinclude_HEADERS = omap_drmif.h
21 19
22pkgconfigdir = @pkgconfigdir@ 20pkgconfigdir = @pkgconfigdir@
23pkgconfig_DATA = libdrm_omap.pc 21pkgconfig_DATA = libdrm_omap.pc
22
23TESTS = omap-symbol-check
24EXTRA_DIST = $(TESTS)
diff --git a/omap/omap-symbol-check b/omap/omap-symbol-check
new file mode 100755
index 00000000..759c84bd
--- /dev/null
+++ b/omap/omap-symbol-check
@@ -0,0 +1,35 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.am/libdrm_omap*HEADERS
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_omap.so} | awk '{print $3}'| while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13omap_bo_cpu_fini
14omap_bo_cpu_prep
15omap_bo_del
16omap_bo_dmabuf
17omap_bo_from_dmabuf
18omap_bo_from_name
19omap_bo_get_name
20omap_bo_handle
21omap_bo_map
22omap_bo_new
23omap_bo_new_tiled
24omap_bo_ref
25omap_bo_size
26omap_device_del
27omap_device_new
28omap_device_ref
29omap_get_param
30omap_set_param
31EOF
32done)
33
34test ! -n "$FUNCS" || echo $FUNCS
35test ! -n "$FUNCS"
diff --git a/omap/omap_drm.c b/omap/omap_drm.c
index 8b4ec466..08ba64eb 100644
--- a/omap/omap_drm.c
+++ b/omap/omap_drm.c
@@ -39,7 +39,7 @@
39#include <unistd.h> 39#include <unistd.h>
40#include <pthread.h> 40#include <pthread.h>
41 41
42#include <libdrm.h> 42#include <libdrm_macros.h>
43#include <xf86drm.h> 43#include <xf86drm.h>
44#include <xf86atomic.h> 44#include <xf86atomic.h>
45 45
@@ -92,7 +92,7 @@ static struct omap_device * omap_device_new_impl(int fd)
92 return dev; 92 return dev;
93} 93}
94 94
95drm_public struct omap_device * omap_device_new(int fd) 95struct omap_device * omap_device_new(int fd)
96{ 96{
97 struct omap_device *dev = NULL; 97 struct omap_device *dev = NULL;
98 98
@@ -115,13 +115,13 @@ drm_public struct omap_device * omap_device_new(int fd)
115 return dev; 115 return dev;
116} 116}
117 117
118drm_public struct omap_device * omap_device_ref(struct omap_device *dev) 118struct omap_device * omap_device_ref(struct omap_device *dev)
119{ 119{
120 atomic_inc(&dev->refcnt); 120 atomic_inc(&dev->refcnt);
121 return dev; 121 return dev;
122} 122}
123 123
124drm_public void omap_device_del(struct omap_device *dev) 124void omap_device_del(struct omap_device *dev)
125{ 125{
126 if (!atomic_dec_and_test(&dev->refcnt)) 126 if (!atomic_dec_and_test(&dev->refcnt))
127 return; 127 return;
@@ -132,7 +132,7 @@ drm_public void omap_device_del(struct omap_device *dev)
132 free(dev); 132 free(dev);
133} 133}
134 134
135drm_public int 135int
136omap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value) 136omap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value)
137{ 137{
138 struct drm_omap_param req = { 138 struct drm_omap_param req = {
@@ -150,7 +150,7 @@ omap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value)
150 return 0; 150 return 0;
151} 151}
152 152
153drm_public int 153int
154omap_set_param(struct omap_device *dev, uint64_t param, uint64_t value) 154omap_set_param(struct omap_device *dev, uint64_t param, uint64_t value)
155{ 155{
156 struct drm_omap_param req = { 156 struct drm_omap_param req = {
@@ -186,6 +186,7 @@ static struct omap_bo * bo_from_handle(struct omap_device *dev,
186 } 186 }
187 bo->dev = omap_device_ref(dev); 187 bo->dev = omap_device_ref(dev);
188 bo->handle = handle; 188 bo->handle = handle;
189 bo->fd = -1;
189 atomic_set(&bo->refcnt, 1); 190 atomic_set(&bo->refcnt, 1);
190 /* add ourselves to the handle table: */ 191 /* add ourselves to the handle table: */
191 drmHashInsert(dev->handle_table, handle, bo); 192 drmHashInsert(dev->handle_table, handle, bo);
@@ -229,7 +230,7 @@ fail:
229 230
230 231
231/* allocate a new (un-tiled) buffer object */ 232/* allocate a new (un-tiled) buffer object */
232drm_public struct omap_bo * 233struct omap_bo *
233omap_bo_new(struct omap_device *dev, uint32_t size, uint32_t flags) 234omap_bo_new(struct omap_device *dev, uint32_t size, uint32_t flags)
234{ 235{
235 union omap_gem_size gsize = { 236 union omap_gem_size gsize = {
@@ -242,7 +243,7 @@ omap_bo_new(struct omap_device *dev, uint32_t size, uint32_t flags)
242} 243}
243 244
244/* allocate a new buffer object */ 245/* allocate a new buffer object */
245drm_public struct omap_bo * 246struct omap_bo *
246omap_bo_new_tiled(struct omap_device *dev, uint32_t width, 247omap_bo_new_tiled(struct omap_device *dev, uint32_t width,
247 uint32_t height, uint32_t flags) 248 uint32_t height, uint32_t flags)
248{ 249{
@@ -258,7 +259,7 @@ omap_bo_new_tiled(struct omap_device *dev, uint32_t width,
258 return omap_bo_new_impl(dev, gsize, flags); 259 return omap_bo_new_impl(dev, gsize, flags);
259} 260}
260 261
261drm_public struct omap_bo *omap_bo_ref(struct omap_bo *bo) 262struct omap_bo *omap_bo_ref(struct omap_bo *bo)
262{ 263{
263 atomic_inc(&bo->refcnt); 264 atomic_inc(&bo->refcnt);
264 return bo; 265 return bo;
@@ -284,7 +285,7 @@ static int get_buffer_info(struct omap_bo *bo)
284} 285}
285 286
286/* import a buffer object from DRI2 name */ 287/* import a buffer object from DRI2 name */
287drm_public struct omap_bo * 288struct omap_bo *
288omap_bo_from_name(struct omap_device *dev, uint32_t name) 289omap_bo_from_name(struct omap_device *dev, uint32_t name)
289{ 290{
290 struct omap_bo *bo = NULL; 291 struct omap_bo *bo = NULL;
@@ -318,7 +319,7 @@ fail:
318 * fd so caller should close() the fd when it is otherwise done 319 * fd so caller should close() the fd when it is otherwise done
319 * with it (even if it is still using the 'struct omap_bo *') 320 * with it (even if it is still using the 'struct omap_bo *')
320 */ 321 */
321drm_public struct omap_bo * 322struct omap_bo *
322omap_bo_from_dmabuf(struct omap_device *dev, int fd) 323omap_bo_from_dmabuf(struct omap_device *dev, int fd)
323{ 324{
324 struct omap_bo *bo = NULL; 325 struct omap_bo *bo = NULL;
@@ -350,7 +351,7 @@ fail:
350} 351}
351 352
352/* destroy a buffer object */ 353/* destroy a buffer object */
353drm_public void omap_bo_del(struct omap_bo *bo) 354void omap_bo_del(struct omap_bo *bo)
354{ 355{
355 if (!bo) { 356 if (!bo) {
356 return; 357 return;
@@ -363,7 +364,7 @@ drm_public void omap_bo_del(struct omap_bo *bo)
363 munmap(bo->map, bo->size); 364 munmap(bo->map, bo->size);
364 } 365 }
365 366
366 if (bo->fd) { 367 if (bo->fd >= 0) {
367 close(bo->fd); 368 close(bo->fd);
368 } 369 }
369 370
@@ -383,7 +384,7 @@ drm_public void omap_bo_del(struct omap_bo *bo)
383} 384}
384 385
385/* get the global flink/DRI2 buffer name */ 386/* get the global flink/DRI2 buffer name */
386drm_public int omap_bo_get_name(struct omap_bo *bo, uint32_t *name) 387int omap_bo_get_name(struct omap_bo *bo, uint32_t *name)
387{ 388{
388 if (!bo->name) { 389 if (!bo->name) {
389 struct drm_gem_flink req = { 390 struct drm_gem_flink req = {
@@ -404,7 +405,7 @@ drm_public int omap_bo_get_name(struct omap_bo *bo, uint32_t *name)
404 return 0; 405 return 0;
405} 406}
406 407
407drm_public uint32_t omap_bo_handle(struct omap_bo *bo) 408uint32_t omap_bo_handle(struct omap_bo *bo)
408{ 409{
409 return bo->handle; 410 return bo->handle;
410} 411}
@@ -412,9 +413,9 @@ drm_public uint32_t omap_bo_handle(struct omap_bo *bo)
412/* caller owns the dmabuf fd that is returned and is responsible 413/* caller owns the dmabuf fd that is returned and is responsible
413 * to close() it when done 414 * to close() it when done
414 */ 415 */
415drm_public int omap_bo_dmabuf(struct omap_bo *bo) 416int omap_bo_dmabuf(struct omap_bo *bo)
416{ 417{
417 if (!bo->fd) { 418 if (bo->fd < 0) {
418 struct drm_prime_handle req = { 419 struct drm_prime_handle req = {
419 .handle = bo->handle, 420 .handle = bo->handle,
420 .flags = DRM_CLOEXEC, 421 .flags = DRM_CLOEXEC,
@@ -431,7 +432,7 @@ drm_public int omap_bo_dmabuf(struct omap_bo *bo)
431 return dup(bo->fd); 432 return dup(bo->fd);
432} 433}
433 434
434drm_public uint32_t omap_bo_size(struct omap_bo *bo) 435uint32_t omap_bo_size(struct omap_bo *bo)
435{ 436{
436 if (!bo->size) { 437 if (!bo->size) {
437 get_buffer_info(bo); 438 get_buffer_info(bo);
@@ -439,7 +440,7 @@ drm_public uint32_t omap_bo_size(struct omap_bo *bo)
439 return bo->size; 440 return bo->size;
440} 441}
441 442
442drm_public void *omap_bo_map(struct omap_bo *bo) 443void *omap_bo_map(struct omap_bo *bo)
443{ 444{
444 if (!bo->map) { 445 if (!bo->map) {
445 if (!bo->offset) { 446 if (!bo->offset) {
@@ -455,7 +456,7 @@ drm_public void *omap_bo_map(struct omap_bo *bo)
455 return bo->map; 456 return bo->map;
456} 457}
457 458
458drm_public int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op) 459int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op)
459{ 460{
460 struct drm_omap_gem_cpu_prep req = { 461 struct drm_omap_gem_cpu_prep req = {
461 .handle = bo->handle, 462 .handle = bo->handle,
@@ -465,7 +466,7 @@ drm_public int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op)
465 DRM_OMAP_GEM_CPU_PREP, &req, sizeof(req)); 466 DRM_OMAP_GEM_CPU_PREP, &req, sizeof(req));
466} 467}
467 468
468drm_public int omap_bo_cpu_fini(struct omap_bo *bo, enum omap_gem_op op) 469int omap_bo_cpu_fini(struct omap_bo *bo, enum omap_gem_op op)
469{ 470{
470 struct drm_omap_gem_cpu_fini req = { 471 struct drm_omap_gem_cpu_fini req = {
471 .handle = bo->handle, 472 .handle = bo->handle,
diff --git a/radeon/Android.mk b/radeon/Android.mk
index 8783c871..890bf541 100644
--- a/radeon/Android.mk
+++ b/radeon/Android.mk
@@ -13,7 +13,4 @@ LOCAL_SRC_FILES := $(filter-out %.h,$(LIBDRM_RADEON_FILES))
13LOCAL_CFLAGS := \ 13LOCAL_CFLAGS := \
14 -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 14 -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1
15 15
16LOCAL_SHARED_LIBRARIES := \
17 libdrm
18
19include $(BUILD_SHARED_LIBRARY) 16include $(BUILD_SHARED_LIBRARY)
diff --git a/radeon/Makefile.am b/radeon/Makefile.am
index 4575065d..25c03d3c 100644
--- a/radeon/Makefile.am
+++ b/radeon/Makefile.am
@@ -26,9 +26,7 @@ include Makefile.sources
26 26
27AM_CFLAGS = \ 27AM_CFLAGS = \
28 $(WARN_CFLAGS) \ 28 $(WARN_CFLAGS) \
29 $(VISIBILITY_CFLAGS) \
30 -I$(top_srcdir) \ 29 -I$(top_srcdir) \
31 -I$(top_srcdir)/radeon \
32 $(PTHREADSTUBS_CFLAGS) \ 30 $(PTHREADSTUBS_CFLAGS) \
33 -I$(top_srcdir)/include/drm 31 -I$(top_srcdir)/include/drm
34 32
@@ -45,4 +43,4 @@ libdrm_radeoninclude_HEADERS = $(LIBDRM_RADEON_H_FILES)
45pkgconfigdir = @pkgconfigdir@ 43pkgconfigdir = @pkgconfigdir@
46pkgconfig_DATA = libdrm_radeon.pc 44pkgconfig_DATA = libdrm_radeon.pc
47 45
48EXTRA_DIST = Android.mk 46EXTRA_DIST = Android.mk $(LIBDRM_RADEON_BOF_FILES) $(TESTS)
diff --git a/radeon/Makefile.sources b/radeon/Makefile.sources
index a17701aa..1cf482a4 100644
--- a/radeon/Makefile.sources
+++ b/radeon/Makefile.sources
@@ -4,9 +4,7 @@ LIBDRM_RADEON_FILES := \
4 radeon_cs_space.c \ 4 radeon_cs_space.c \
5 radeon_bo.c \ 5 radeon_bo.c \
6 radeon_cs.c \ 6 radeon_cs.c \
7 radeon_surface.c \ 7 radeon_surface.c
8 bof.c \
9 bof.h
10 8
11LIBDRM_RADEON_H_FILES := \ 9LIBDRM_RADEON_H_FILES := \
12 radeon_bo.h \ 10 radeon_bo.h \
@@ -17,3 +15,7 @@ LIBDRM_RADEON_H_FILES := \
17 radeon_bo_int.h \ 15 radeon_bo_int.h \
18 radeon_cs_int.h \ 16 radeon_cs_int.h \
19 r600_pci_ids.h 17 r600_pci_ids.h
18
19LIBDRM_RADEON_BOF_FILES := \
20 bof.c \
21 bof.h
diff --git a/radeon/r600_pci_ids.h b/radeon/r600_pci_ids.h
index 3e1136db..a3b2eac8 100644
--- a/radeon/r600_pci_ids.h
+++ b/radeon/r600_pci_ids.h
@@ -391,6 +391,7 @@ CHIPSET(0x6608, OLAND_6608, OLAND)
391CHIPSET(0x6610, OLAND_6610, OLAND) 391CHIPSET(0x6610, OLAND_6610, OLAND)
392CHIPSET(0x6611, OLAND_6611, OLAND) 392CHIPSET(0x6611, OLAND_6611, OLAND)
393CHIPSET(0x6613, OLAND_6613, OLAND) 393CHIPSET(0x6613, OLAND_6613, OLAND)
394CHIPSET(0x6617, OLAND_6617, OLAND)
394CHIPSET(0x6620, OLAND_6620, OLAND) 395CHIPSET(0x6620, OLAND_6620, OLAND)
395CHIPSET(0x6621, OLAND_6621, OLAND) 396CHIPSET(0x6621, OLAND_6621, OLAND)
396CHIPSET(0x6623, OLAND_6623, OLAND) 397CHIPSET(0x6623, OLAND_6623, OLAND)
@@ -413,6 +414,7 @@ CHIPSET(0x6651, BONAIRE_6651, BONAIRE)
413CHIPSET(0x6658, BONAIRE_6658, BONAIRE) 414CHIPSET(0x6658, BONAIRE_6658, BONAIRE)
414CHIPSET(0x665C, BONAIRE_665C, BONAIRE) 415CHIPSET(0x665C, BONAIRE_665C, BONAIRE)
415CHIPSET(0x665D, BONAIRE_665D, BONAIRE) 416CHIPSET(0x665D, BONAIRE_665D, BONAIRE)
417CHIPSET(0x665F, BONAIRE_665F, BONAIRE)
416 418
417CHIPSET(0x9830, KABINI_9830, KABINI) 419CHIPSET(0x9830, KABINI_9830, KABINI)
418CHIPSET(0x9831, KABINI_9831, KABINI) 420CHIPSET(0x9831, KABINI_9831, KABINI)
diff --git a/radeon/radeon-symbol-check b/radeon/radeon-symbol-check
new file mode 100755
index 00000000..0bf2ffcb
--- /dev/null
+++ b/radeon/radeon-symbol-check
@@ -0,0 +1,61 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.sources/LIBDRM_RADEON_H_FILES
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_radeon.so} | awk '{print $3}'| while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13radeon_bo_debug
14radeon_bo_get_handle
15radeon_bo_get_src_domain
16radeon_bo_get_tiling
17radeon_bo_is_busy
18radeon_bo_is_referenced_by_cs
19radeon_bo_is_static
20radeon_bo_manager_gem_ctor
21radeon_bo_manager_gem_dtor
22radeon_bo_map
23radeon_bo_open
24radeon_bo_ref
25radeon_bo_set_tiling
26radeon_bo_unmap
27radeon_bo_unref
28radeon_bo_wait
29radeon_cs_begin
30radeon_cs_create
31radeon_cs_destroy
32radeon_cs_emit
33radeon_cs_end
34radeon_cs_erase
35radeon_cs_get_id
36radeon_cs_manager_gem_ctor
37radeon_cs_manager_gem_dtor
38radeon_cs_need_flush
39radeon_cs_print
40radeon_cs_set_limit
41radeon_cs_space_add_persistent_bo
42radeon_cs_space_check
43radeon_cs_space_check_with_bo
44radeon_cs_space_reset_bos
45radeon_cs_space_set_flush
46radeon_cs_write_reloc
47radeon_gem_bo_open_prime
48radeon_gem_get_kernel_name
49radeon_gem_get_reloc_in_cs
50radeon_gem_name_bo
51radeon_gem_prime_share_bo
52radeon_gem_set_domain
53radeon_surface_best
54radeon_surface_init
55radeon_surface_manager_free
56radeon_surface_manager_new
57EOF
58done)
59
60test ! -n "$FUNCS" || echo $FUNCS
61test ! -n "$FUNCS"
diff --git a/radeon/radeon_bo.c b/radeon/radeon_bo.c
index 865e3f7e..447f9280 100644
--- a/radeon/radeon_bo.c
+++ b/radeon/radeon_bo.c
@@ -32,11 +32,11 @@
32#ifdef HAVE_CONFIG_H 32#ifdef HAVE_CONFIG_H
33#include <config.h> 33#include <config.h>
34#endif 34#endif
35#include <libdrm.h> 35#include <libdrm_macros.h>
36#include <radeon_bo.h> 36#include <radeon_bo.h>
37#include <radeon_bo_int.h> 37#include <radeon_bo_int.h>
38 38
39drm_public void radeon_bo_debug(struct radeon_bo *bo, const char *op) 39void radeon_bo_debug(struct radeon_bo *bo, const char *op)
40{ 40{
41 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 41 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
42 42
@@ -44,7 +44,7 @@ drm_public void radeon_bo_debug(struct radeon_bo *bo, const char *op)
44 op, bo, bo->handle, boi->size, boi->cref); 44 op, bo, bo->handle, boi->size, boi->cref);
45} 45}
46 46
47drm_public struct radeon_bo * 47struct radeon_bo *
48radeon_bo_open(struct radeon_bo_manager *bom, uint32_t handle, uint32_t size, 48radeon_bo_open(struct radeon_bo_manager *bom, uint32_t handle, uint32_t size,
49 uint32_t alignment, uint32_t domains, uint32_t flags) 49 uint32_t alignment, uint32_t domains, uint32_t flags)
50{ 50{
@@ -53,14 +53,14 @@ radeon_bo_open(struct radeon_bo_manager *bom, uint32_t handle, uint32_t size,
53 return bo; 53 return bo;
54} 54}
55 55
56drm_public void radeon_bo_ref(struct radeon_bo *bo) 56void radeon_bo_ref(struct radeon_bo *bo)
57{ 57{
58 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 58 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
59 boi->cref++; 59 boi->cref++;
60 boi->bom->funcs->bo_ref(boi); 60 boi->bom->funcs->bo_ref(boi);
61} 61}
62 62
63drm_public struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo) 63struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo)
64{ 64{
65 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 65 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
66 if (bo == NULL) 66 if (bo == NULL)
@@ -70,19 +70,19 @@ drm_public struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo)
70 return boi->bom->funcs->bo_unref(boi); 70 return boi->bom->funcs->bo_unref(boi);
71} 71}
72 72
73drm_public int radeon_bo_map(struct radeon_bo *bo, int write) 73int radeon_bo_map(struct radeon_bo *bo, int write)
74{ 74{
75 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 75 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
76 return boi->bom->funcs->bo_map(boi, write); 76 return boi->bom->funcs->bo_map(boi, write);
77} 77}
78 78
79drm_public int radeon_bo_unmap(struct radeon_bo *bo) 79int radeon_bo_unmap(struct radeon_bo *bo)
80{ 80{
81 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 81 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
82 return boi->bom->funcs->bo_unmap(boi); 82 return boi->bom->funcs->bo_unmap(boi);
83} 83}
84 84
85drm_public int radeon_bo_wait(struct radeon_bo *bo) 85int radeon_bo_wait(struct radeon_bo *bo)
86{ 86{
87 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 87 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
88 if (!boi->bom->funcs->bo_wait) 88 if (!boi->bom->funcs->bo_wait)
@@ -90,13 +90,13 @@ drm_public int radeon_bo_wait(struct radeon_bo *bo)
90 return boi->bom->funcs->bo_wait(boi); 90 return boi->bom->funcs->bo_wait(boi);
91} 91}
92 92
93drm_public int radeon_bo_is_busy(struct radeon_bo *bo, uint32_t *domain) 93int radeon_bo_is_busy(struct radeon_bo *bo, uint32_t *domain)
94{ 94{
95 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 95 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
96 return boi->bom->funcs->bo_is_busy(boi, domain); 96 return boi->bom->funcs->bo_is_busy(boi, domain);
97} 97}
98 98
99drm_public int 99int
100radeon_bo_set_tiling(struct radeon_bo *bo, 100radeon_bo_set_tiling(struct radeon_bo *bo,
101 uint32_t tiling_flags, uint32_t pitch) 101 uint32_t tiling_flags, uint32_t pitch)
102{ 102{
@@ -104,7 +104,7 @@ radeon_bo_set_tiling(struct radeon_bo *bo,
104 return boi->bom->funcs->bo_set_tiling(boi, tiling_flags, pitch); 104 return boi->bom->funcs->bo_set_tiling(boi, tiling_flags, pitch);
105} 105}
106 106
107drm_public int 107int
108radeon_bo_get_tiling(struct radeon_bo *bo, 108radeon_bo_get_tiling(struct radeon_bo *bo,
109 uint32_t *tiling_flags, uint32_t *pitch) 109 uint32_t *tiling_flags, uint32_t *pitch)
110{ 110{
@@ -112,7 +112,7 @@ radeon_bo_get_tiling(struct radeon_bo *bo,
112 return boi->bom->funcs->bo_get_tiling(boi, tiling_flags, pitch); 112 return boi->bom->funcs->bo_get_tiling(boi, tiling_flags, pitch);
113} 113}
114 114
115drm_public int radeon_bo_is_static(struct radeon_bo *bo) 115int radeon_bo_is_static(struct radeon_bo *bo)
116{ 116{
117 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 117 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
118 if (boi->bom->funcs->bo_is_static) 118 if (boi->bom->funcs->bo_is_static)
@@ -120,19 +120,19 @@ drm_public int radeon_bo_is_static(struct radeon_bo *bo)
120 return 0; 120 return 0;
121} 121}
122 122
123drm_public int 123int
124radeon_bo_is_referenced_by_cs(struct radeon_bo *bo, struct radeon_cs *cs) 124radeon_bo_is_referenced_by_cs(struct radeon_bo *bo, struct radeon_cs *cs)
125{ 125{
126 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 126 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
127 return boi->cref > 1; 127 return boi->cref > 1;
128} 128}
129 129
130drm_public uint32_t radeon_bo_get_handle(struct radeon_bo *bo) 130uint32_t radeon_bo_get_handle(struct radeon_bo *bo)
131{ 131{
132 return bo->handle; 132 return bo->handle;
133} 133}
134 134
135drm_public uint32_t radeon_bo_get_src_domain(struct radeon_bo *bo) 135uint32_t radeon_bo_get_src_domain(struct radeon_bo *bo)
136{ 136{
137 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 137 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
138 uint32_t src_domain; 138 uint32_t src_domain;
diff --git a/radeon/radeon_bo_gem.c b/radeon/radeon_bo_gem.c
index e78303a7..c9fe19ff 100644
--- a/radeon/radeon_bo_gem.c
+++ b/radeon/radeon_bo_gem.c
@@ -37,7 +37,7 @@
37#include <stdlib.h> 37#include <stdlib.h>
38#include <string.h> 38#include <string.h>
39#include <errno.h> 39#include <errno.h>
40#include "libdrm.h" 40#include "libdrm_macros.h"
41#include "xf86drm.h" 41#include "xf86drm.h"
42#include "xf86atomic.h" 42#include "xf86atomic.h"
43#include "drm.h" 43#include "drm.h"
@@ -270,20 +270,21 @@ static int bo_get_tiling(struct radeon_bo_int *boi, uint32_t *tiling_flags,
270 return r; 270 return r;
271} 271}
272 272
273static struct radeon_bo_funcs bo_gem_funcs = { 273static const struct radeon_bo_funcs bo_gem_funcs = {
274 bo_open, 274 .bo_open = bo_open,
275 bo_ref, 275 .bo_ref = bo_ref,
276 bo_unref, 276 .bo_unref = bo_unref,
277 bo_map, 277 .bo_map = bo_map,
278 bo_unmap, 278 .bo_unmap = bo_unmap,
279 bo_wait, 279 .bo_wait = bo_wait,
280 NULL, 280 .bo_is_static = NULL,
281 bo_set_tiling, 281 .bo_set_tiling = bo_set_tiling,
282 bo_get_tiling, 282 .bo_get_tiling = bo_get_tiling,
283 bo_is_busy, 283 .bo_is_busy = bo_is_busy,
284 .bo_is_referenced_by_cs = NULL,
284}; 285};
285 286
286drm_public struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd) 287struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
287{ 288{
288 struct bo_manager_gem *bomg; 289 struct bo_manager_gem *bomg;
289 290
@@ -296,7 +297,7 @@ drm_public struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
296 return (struct radeon_bo_manager*)bomg; 297 return (struct radeon_bo_manager*)bomg;
297} 298}
298 299
299drm_public void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom) 300void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
300{ 301{
301 struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom; 302 struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
302 303
@@ -306,21 +307,21 @@ drm_public void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
306 free(bomg); 307 free(bomg);
307} 308}
308 309
309drm_public uint32_t 310uint32_t
310radeon_gem_name_bo(struct radeon_bo *bo) 311radeon_gem_name_bo(struct radeon_bo *bo)
311{ 312{
312 struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; 313 struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
313 return bo_gem->name; 314 return bo_gem->name;
314} 315}
315 316
316drm_public void * 317void *
317radeon_gem_get_reloc_in_cs(struct radeon_bo *bo) 318radeon_gem_get_reloc_in_cs(struct radeon_bo *bo)
318{ 319{
319 struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; 320 struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
320 return &bo_gem->reloc_in_cs; 321 return &bo_gem->reloc_in_cs;
321} 322}
322 323
323drm_public int 324int
324radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name) 325radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
325{ 326{
326 struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; 327 struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
@@ -342,7 +343,7 @@ radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
342 return 0; 343 return 0;
343} 344}
344 345
345drm_public int 346int
346radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) 347radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
347{ 348{
348 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 349 struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
@@ -360,7 +361,7 @@ radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t writ
360 return r; 361 return r;
361} 362}
362 363
363drm_public int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle) 364int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
364{ 365{
365 struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; 366 struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
366 int ret; 367 int ret;
@@ -369,7 +370,7 @@ drm_public int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
369 return ret; 370 return ret;
370} 371}
371 372
372drm_public struct radeon_bo * 373struct radeon_bo *
373radeon_gem_bo_open_prime(struct radeon_bo_manager *bom, int fd_handle, uint32_t size) 374radeon_gem_bo_open_prime(struct radeon_bo_manager *bom, int fd_handle, uint32_t size)
374{ 375{
375 struct radeon_bo_gem *bo; 376 struct radeon_bo_gem *bo;
diff --git a/radeon/radeon_bo_int.h b/radeon/radeon_bo_int.h
index 9589ead1..de981b0a 100644
--- a/radeon/radeon_bo_int.h
+++ b/radeon/radeon_bo_int.h
@@ -2,7 +2,7 @@
2#define RADEON_BO_INT 2#define RADEON_BO_INT
3 3
4struct radeon_bo_manager { 4struct radeon_bo_manager {
5 struct radeon_bo_funcs *funcs; 5 const struct radeon_bo_funcs *funcs;
6 int fd; 6 int fd;
7}; 7};
8 8
diff --git a/radeon/radeon_cs.c b/radeon/radeon_cs.c
index fe5bbcec..dffb869f 100644
--- a/radeon/radeon_cs.c
+++ b/radeon/radeon_cs.c
@@ -1,19 +1,19 @@
1#ifdef HAVE_CONFIG_H 1#ifdef HAVE_CONFIG_H
2#include <config.h> 2#include <config.h>
3#endif 3#endif
4#include "libdrm.h" 4#include "libdrm_macros.h"
5#include <stdio.h> 5#include <stdio.h>
6#include "radeon_cs.h" 6#include "radeon_cs.h"
7#include "radeon_cs_int.h" 7#include "radeon_cs_int.h"
8 8
9drm_public struct radeon_cs * 9struct radeon_cs *
10radeon_cs_create(struct radeon_cs_manager *csm, uint32_t ndw) 10radeon_cs_create(struct radeon_cs_manager *csm, uint32_t ndw)
11{ 11{
12 struct radeon_cs_int *csi = csm->funcs->cs_create(csm, ndw); 12 struct radeon_cs_int *csi = csm->funcs->cs_create(csm, ndw);
13 return (struct radeon_cs *)csi; 13 return (struct radeon_cs *)csi;
14} 14}
15 15
16drm_public int 16int
17radeon_cs_write_reloc(struct radeon_cs *cs, struct radeon_bo *bo, 17radeon_cs_write_reloc(struct radeon_cs *cs, struct radeon_bo *bo,
18 uint32_t read_domain, uint32_t write_domain, 18 uint32_t read_domain, uint32_t write_domain,
19 uint32_t flags) 19 uint32_t flags)
@@ -27,7 +27,7 @@ radeon_cs_write_reloc(struct radeon_cs *cs, struct radeon_bo *bo,
27 flags); 27 flags);
28} 28}
29 29
30drm_public int 30int
31radeon_cs_begin(struct radeon_cs *cs, uint32_t ndw, 31radeon_cs_begin(struct radeon_cs *cs, uint32_t ndw,
32 const char *file, const char *func, int line) 32 const char *file, const char *func, int line)
33{ 33{
@@ -35,7 +35,7 @@ radeon_cs_begin(struct radeon_cs *cs, uint32_t ndw,
35 return csi->csm->funcs->cs_begin(csi, ndw, file, func, line); 35 return csi->csm->funcs->cs_begin(csi, ndw, file, func, line);
36} 36}
37 37
38drm_public int 38int
39radeon_cs_end(struct radeon_cs *cs, 39radeon_cs_end(struct radeon_cs *cs,
40 const char *file, const char *func, int line) 40 const char *file, const char *func, int line)
41{ 41{
@@ -43,37 +43,37 @@ radeon_cs_end(struct radeon_cs *cs,
43 return csi->csm->funcs->cs_end(csi, file, func, line); 43 return csi->csm->funcs->cs_end(csi, file, func, line);
44} 44}
45 45
46drm_public int radeon_cs_emit(struct radeon_cs *cs) 46int radeon_cs_emit(struct radeon_cs *cs)
47{ 47{
48 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 48 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
49 return csi->csm->funcs->cs_emit(csi); 49 return csi->csm->funcs->cs_emit(csi);
50} 50}
51 51
52drm_public int radeon_cs_destroy(struct radeon_cs *cs) 52int radeon_cs_destroy(struct radeon_cs *cs)
53{ 53{
54 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 54 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
55 return csi->csm->funcs->cs_destroy(csi); 55 return csi->csm->funcs->cs_destroy(csi);
56} 56}
57 57
58drm_public int radeon_cs_erase(struct radeon_cs *cs) 58int radeon_cs_erase(struct radeon_cs *cs)
59{ 59{
60 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 60 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
61 return csi->csm->funcs->cs_erase(csi); 61 return csi->csm->funcs->cs_erase(csi);
62} 62}
63 63
64drm_public int radeon_cs_need_flush(struct radeon_cs *cs) 64int radeon_cs_need_flush(struct radeon_cs *cs)
65{ 65{
66 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 66 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
67 return csi->csm->funcs->cs_need_flush(csi); 67 return csi->csm->funcs->cs_need_flush(csi);
68} 68}
69 69
70drm_public void radeon_cs_print(struct radeon_cs *cs, FILE *file) 70void radeon_cs_print(struct radeon_cs *cs, FILE *file)
71{ 71{
72 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 72 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
73 csi->csm->funcs->cs_print(csi, file); 73 csi->csm->funcs->cs_print(csi, file);
74} 74}
75 75
76drm_public void 76void
77radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit) 77radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
78{ 78{
79 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 79 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
@@ -83,7 +83,7 @@ radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
83 csi->csm->gart_limit = limit; 83 csi->csm->gart_limit = limit;
84} 84}
85 85
86drm_public void radeon_cs_space_set_flush(struct radeon_cs *cs, 86void radeon_cs_space_set_flush(struct radeon_cs *cs,
87 void (*fn)(void *), void *data) 87 void (*fn)(void *), void *data)
88{ 88{
89 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 89 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
@@ -91,7 +91,7 @@ drm_public void radeon_cs_space_set_flush(struct radeon_cs *cs,
91 csi->space_flush_data = data; 91 csi->space_flush_data = data;
92} 92}
93 93
94drm_public uint32_t radeon_cs_get_id(struct radeon_cs *cs) 94uint32_t radeon_cs_get_id(struct radeon_cs *cs)
95{ 95{
96 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 96 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
97 return csi->id; 97 return csi->id;
diff --git a/radeon/radeon_cs_gem.c b/radeon/radeon_cs_gem.c
index 705ee056..cdec64e0 100644
--- a/radeon/radeon_cs_gem.c
+++ b/radeon/radeon_cs_gem.c
@@ -44,13 +44,16 @@
44#include "radeon_cs_gem.h" 44#include "radeon_cs_gem.h"
45#include "radeon_bo_gem.h" 45#include "radeon_bo_gem.h"
46#include "drm.h" 46#include "drm.h"
47#include "libdrm.h" 47#include "libdrm_macros.h"
48#include "xf86drm.h" 48#include "xf86drm.h"
49#include "xf86atomic.h" 49#include "xf86atomic.h"
50#include "radeon_drm.h" 50#include "radeon_drm.h"
51#include "bof.h"
52 51
52/* Add LIBDRM_RADEON_BOF_FILES to libdrm_radeon_la_SOURCES when building with BOF_DUMP */
53#define CS_BOF_DUMP 0 53#define CS_BOF_DUMP 0
54#if CS_BOF_DUMP
55#include "bof.h"
56#endif
54 57
55struct radeon_cs_manager_gem { 58struct radeon_cs_manager_gem {
56 struct radeon_cs_manager base; 59 struct radeon_cs_manager base;
@@ -511,16 +514,16 @@ static void cs_gem_print(struct radeon_cs_int *cs, FILE *file)
511 } 514 }
512} 515}
513 516
514static struct radeon_cs_funcs radeon_cs_gem_funcs = { 517static const struct radeon_cs_funcs radeon_cs_gem_funcs = {
515 cs_gem_create, 518 .cs_create = cs_gem_create,
516 cs_gem_write_reloc, 519 .cs_write_reloc = cs_gem_write_reloc,
517 cs_gem_begin, 520 .cs_begin = cs_gem_begin,
518 cs_gem_end, 521 .cs_end = cs_gem_end,
519 cs_gem_emit, 522 .cs_emit = cs_gem_emit,
520 cs_gem_destroy, 523 .cs_destroy = cs_gem_destroy,
521 cs_gem_erase, 524 .cs_erase = cs_gem_erase,
522 cs_gem_need_flush, 525 .cs_need_flush = cs_gem_need_flush,
523 cs_gem_print, 526 .cs_print = cs_gem_print,
524}; 527};
525 528
526static int radeon_get_device_id(int fd, uint32_t *device_id) 529static int radeon_get_device_id(int fd, uint32_t *device_id)
@@ -536,7 +539,7 @@ static int radeon_get_device_id(int fd, uint32_t *device_id)
536 return r; 539 return r;
537} 540}
538 541
539drm_public struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd) 542struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
540{ 543{
541 struct radeon_cs_manager_gem *csm; 544 struct radeon_cs_manager_gem *csm;
542 545
@@ -550,7 +553,7 @@ drm_public struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
550 return &csm->base; 553 return &csm->base;
551} 554}
552 555
553drm_public void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm) 556void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
554{ 557{
555 free(csm); 558 free(csm);
556} 559}
diff --git a/radeon/radeon_cs_int.h b/radeon/radeon_cs_int.h
index 6cee5742..d906ad43 100644
--- a/radeon/radeon_cs_int.h
+++ b/radeon/radeon_cs_int.h
@@ -58,7 +58,7 @@ struct radeon_cs_funcs {
58}; 58};
59 59
60struct radeon_cs_manager { 60struct radeon_cs_manager {
61 struct radeon_cs_funcs *funcs; 61 const struct radeon_cs_funcs *funcs;
62 int fd; 62 int fd;
63 int32_t vram_limit, gart_limit; 63 int32_t vram_limit, gart_limit;
64 int32_t vram_write_used, gart_write_used; 64 int32_t vram_write_used, gart_write_used;
diff --git a/radeon/radeon_cs_space.c b/radeon/radeon_cs_space.c
index cca650bf..69287be5 100644
--- a/radeon/radeon_cs_space.c
+++ b/radeon/radeon_cs_space.c
@@ -31,7 +31,7 @@
31#include <assert.h> 31#include <assert.h>
32#include <errno.h> 32#include <errno.h>
33#include <stdlib.h> 33#include <stdlib.h>
34#include "libdrm.h" 34#include "libdrm_macros.h"
35#include "radeon_cs.h" 35#include "radeon_cs.h"
36#include "radeon_bo_int.h" 36#include "radeon_bo_int.h"
37#include "radeon_cs_int.h" 37#include "radeon_cs_int.h"
@@ -165,7 +165,7 @@ static int radeon_cs_do_space_check(struct radeon_cs_int *cs, struct radeon_cs_s
165 return RADEON_CS_SPACE_OK; 165 return RADEON_CS_SPACE_OK;
166} 166}
167 167
168drm_public void 168void
169radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo, 169radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo,
170 uint32_t read_domains, uint32_t write_domain) 170 uint32_t read_domains, uint32_t write_domain)
171{ 171{
@@ -209,7 +209,7 @@ again:
209 return 0; 209 return 0;
210} 210}
211 211
212drm_public int 212int
213radeon_cs_space_check_with_bo(struct radeon_cs *cs, struct radeon_bo *bo, 213radeon_cs_space_check_with_bo(struct radeon_cs *cs, struct radeon_bo *bo,
214 uint32_t read_domains, uint32_t write_domain) 214 uint32_t read_domains, uint32_t write_domain)
215{ 215{
@@ -230,13 +230,13 @@ radeon_cs_space_check_with_bo(struct radeon_cs *cs, struct radeon_bo *bo,
230 return ret; 230 return ret;
231} 231}
232 232
233drm_public int radeon_cs_space_check(struct radeon_cs *cs) 233int radeon_cs_space_check(struct radeon_cs *cs)
234{ 234{
235 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 235 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
236 return radeon_cs_check_space_internal(csi, NULL); 236 return radeon_cs_check_space_internal(csi, NULL);
237} 237}
238 238
239drm_public void radeon_cs_space_reset_bos(struct radeon_cs *cs) 239void radeon_cs_space_reset_bos(struct radeon_cs *cs)
240{ 240{
241 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; 241 struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
242 int i; 242 int i;
diff --git a/radeon/radeon_surface.c b/radeon/radeon_surface.c
index bd9ee6d1..5ec97454 100644
--- a/radeon/radeon_surface.c
+++ b/radeon/radeon_surface.c
@@ -37,7 +37,7 @@
37#include <string.h> 37#include <string.h>
38#include <sys/ioctl.h> 38#include <sys/ioctl.h>
39#include "drm.h" 39#include "drm.h"
40#include "libdrm.h" 40#include "libdrm_macros.h"
41#include "xf86drm.h" 41#include "xf86drm.h"
42#include "radeon_drm.h" 42#include "radeon_drm.h"
43#include "radeon_surface.h" 43#include "radeon_surface.h"
@@ -163,7 +163,7 @@ static void surf_minify(struct radeon_surface *surf,
163 struct radeon_surface_level *surflevel, 163 struct radeon_surface_level *surflevel,
164 unsigned bpe, unsigned level, 164 unsigned bpe, unsigned level,
165 uint32_t xalign, uint32_t yalign, uint32_t zalign, 165 uint32_t xalign, uint32_t yalign, uint32_t zalign,
166 unsigned offset) 166 uint64_t offset)
167{ 167{
168 surflevel->npix_x = mip_minify(surf->npix_x, level); 168 surflevel->npix_x = mip_minify(surf->npix_x, level);
169 surflevel->npix_y = mip_minify(surf->npix_y, level); 169 surflevel->npix_y = mip_minify(surf->npix_y, level);
@@ -184,7 +184,7 @@ static void surf_minify(struct radeon_surface *surf,
184 184
185 surflevel->offset = offset; 185 surflevel->offset = offset;
186 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples; 186 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
187 surflevel->slice_size = surflevel->pitch_bytes * surflevel->nblk_y; 187 surflevel->slice_size = (uint64_t)surflevel->pitch_bytes * surflevel->nblk_y;
188 188
189 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; 189 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
190} 190}
@@ -570,7 +570,7 @@ static void eg_surf_minify(struct radeon_surface *surf,
570 unsigned mtilew, 570 unsigned mtilew,
571 unsigned mtileh, 571 unsigned mtileh,
572 unsigned mtileb, 572 unsigned mtileb,
573 unsigned offset) 573 uint64_t offset)
574{ 574{
575 unsigned mtile_pr, mtile_ps; 575 unsigned mtile_pr, mtile_ps;
576 576
@@ -598,7 +598,7 @@ static void eg_surf_minify(struct radeon_surface *surf,
598 598
599 surflevel->offset = offset; 599 surflevel->offset = offset;
600 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples; 600 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
601 surflevel->slice_size = mtile_ps * mtileb * slice_pt; 601 surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
602 602
603 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; 603 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
604} 604}
@@ -785,7 +785,7 @@ static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
785{ 785{
786 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER; 786 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
787 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags; 787 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
788 /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */ 788 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
789 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL]; 789 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
790 struct radeon_surface_level *stencil_level = 790 struct radeon_surface_level *stencil_level =
791 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp; 791 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
@@ -807,7 +807,7 @@ static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
807{ 807{
808 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER; 808 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
809 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags; 809 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
810 /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */ 810 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
811 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL]; 811 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
812 struct radeon_surface_level *stencil_level = 812 struct radeon_surface_level *stencil_level =
813 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp; 813 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
@@ -1415,7 +1415,7 @@ static void si_surf_minify(struct radeon_surface *surf,
1415 struct radeon_surface_level *surflevel, 1415 struct radeon_surface_level *surflevel,
1416 unsigned bpe, unsigned level, 1416 unsigned bpe, unsigned level,
1417 uint32_t xalign, uint32_t yalign, uint32_t zalign, 1417 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1418 uint32_t slice_align, unsigned offset) 1418 uint32_t slice_align, uint64_t offset)
1419{ 1419{
1420 if (level == 0) { 1420 if (level == 0) {
1421 surflevel->npix_x = surf->npix_x; 1421 surflevel->npix_x = surf->npix_x;
@@ -1453,7 +1453,8 @@ static void si_surf_minify(struct radeon_surface *surf,
1453 1453
1454 surflevel->offset = offset; 1454 surflevel->offset = offset;
1455 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples; 1455 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1456 surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align); 1456 surflevel->slice_size = ALIGN((uint64_t)surflevel->pitch_bytes * surflevel->nblk_y,
1457 (uint64_t)slice_align);
1457 1458
1458 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; 1459 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1459} 1460}
@@ -1462,7 +1463,7 @@ static void si_surf_minify_2d(struct radeon_surface *surf,
1462 struct radeon_surface_level *surflevel, 1463 struct radeon_surface_level *surflevel,
1463 unsigned bpe, unsigned level, unsigned slice_pt, 1464 unsigned bpe, unsigned level, unsigned slice_pt,
1464 uint32_t xalign, uint32_t yalign, uint32_t zalign, 1465 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1465 unsigned mtileb, unsigned offset) 1466 unsigned mtileb, uint64_t offset)
1466{ 1467{
1467 unsigned mtile_pr, mtile_ps; 1468 unsigned mtile_pr, mtile_ps;
1468 1469
@@ -1501,7 +1502,7 @@ static void si_surf_minify_2d(struct radeon_surface *surf,
1501 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign; 1502 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1502 surflevel->offset = offset; 1503 surflevel->offset = offset;
1503 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples; 1504 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1504 surflevel->slice_size = mtile_ps * mtileb * slice_pt; 1505 surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
1505 1506
1506 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; 1507 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1507} 1508}
@@ -2400,7 +2401,7 @@ static int cik_surface_best(struct radeon_surface_manager *surf_man,
2400/* =========================================================================== 2401/* ===========================================================================
2401 * public API 2402 * public API
2402 */ 2403 */
2403drm_public struct radeon_surface_manager * 2404struct radeon_surface_manager *
2404radeon_surface_manager_new(int fd) 2405radeon_surface_manager_new(int fd)
2405{ 2406{
2406 struct radeon_surface_manager *surf_man; 2407 struct radeon_surface_manager *surf_man;
@@ -2449,7 +2450,7 @@ out_err:
2449 return NULL; 2450 return NULL;
2450} 2451}
2451 2452
2452drm_public void 2453void
2453radeon_surface_manager_free(struct radeon_surface_manager *surf_man) 2454radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2454{ 2455{
2455 free(surf_man); 2456 free(surf_man);
@@ -2522,7 +2523,7 @@ static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2522 return 0; 2523 return 0;
2523} 2524}
2524 2525
2525drm_public int 2526int
2526radeon_surface_init(struct radeon_surface_manager *surf_man, 2527radeon_surface_init(struct radeon_surface_manager *surf_man,
2527 struct radeon_surface *surf) 2528 struct radeon_surface *surf)
2528{ 2529{
@@ -2539,7 +2540,7 @@ radeon_surface_init(struct radeon_surface_manager *surf_man,
2539 return surf_man->surface_init(surf_man, surf); 2540 return surf_man->surface_init(surf_man, surf);
2540} 2541}
2541 2542
2542drm_public int 2543int
2543radeon_surface_best(struct radeon_surface_manager *surf_man, 2544radeon_surface_best(struct radeon_surface_manager *surf_man,
2544 struct radeon_surface *surf) 2545 struct radeon_surface *surf)
2545{ 2546{
diff --git a/tegra/Makefile.am b/tegra/Makefile.am
index a6474879..fb40be55 100644
--- a/tegra/Makefile.am
+++ b/tegra/Makefile.am
@@ -4,7 +4,6 @@ AM_CPPFLAGS = \
4 4
5AM_CFLAGS = \ 5AM_CFLAGS = \
6 @PTHREADSTUBS_CFLAGS@ \ 6 @PTHREADSTUBS_CFLAGS@ \
7 $(VISIBILITY_CFLAGS) \
8 $(WARN_CFLAGS) 7 $(WARN_CFLAGS)
9 8
10libdrm_tegra_ladir = $(libdir) 9libdrm_tegra_ladir = $(libdir)
@@ -21,3 +20,6 @@ libdrm_tegrainclude_HEADERS = tegra.h
21 20
22pkgconfigdir = @pkgconfigdir@ 21pkgconfigdir = @pkgconfigdir@
23pkgconfig_DATA = libdrm_tegra.pc 22pkgconfig_DATA = libdrm_tegra.pc
23
24TESTS = tegra-symbol-check
25EXTRA_DIST = $(TESTS)
diff --git a/tegra/private.h b/tegra/private.h
index 1b490d40..571caa56 100644
--- a/tegra/private.h
+++ b/tegra/private.h
@@ -28,7 +28,7 @@
28#include <stdbool.h> 28#include <stdbool.h>
29#include <stdint.h> 29#include <stdint.h>
30 30
31#include <libdrm.h> 31#include <libdrm_macros.h>
32#include <xf86atomic.h> 32#include <xf86atomic.h>
33 33
34#include "tegra.h" 34#include "tegra.h"
diff --git a/tegra/tegra-symbol-check b/tegra/tegra-symbol-check
new file mode 100755
index 00000000..40208311
--- /dev/null
+++ b/tegra/tegra-symbol-check
@@ -0,0 +1,30 @@
1#!/bin/bash
2
3# The following symbols (past the first five) are taken from the public headers.
4# A list of the latter should be available Makefile.sources/LIBDRM_FREEDRENO_H_FILES
5
6FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_tegra.so} | awk '{print $3}'| while read func; do
7( grep -q "^$func$" || echo $func ) <<EOF
8__bss_start
9_edata
10_end
11_fini
12_init
13drm_tegra_bo_get_flags
14drm_tegra_bo_get_handle
15drm_tegra_bo_get_tiling
16drm_tegra_bo_map
17drm_tegra_bo_new
18drm_tegra_bo_ref
19drm_tegra_bo_set_flags
20drm_tegra_bo_set_tiling
21drm_tegra_bo_unmap
22drm_tegra_bo_unref
23drm_tegra_bo_wrap
24drm_tegra_close
25drm_tegra_new
26EOF
27done)
28
29test ! -n "$FUNCS" || echo $FUNCS
30test ! -n "$FUNCS"
diff --git a/tegra/tegra.c b/tegra/tegra.c
index a58a08a5..66f19e96 100644
--- a/tegra/tegra.c
+++ b/tegra/tegra.c
@@ -74,7 +74,6 @@ static int drm_tegra_wrap(struct drm_tegra **drmp, int fd, bool close)
74 return 0; 74 return 0;
75} 75}
76 76
77drm_public
78int drm_tegra_new(struct drm_tegra **drmp, int fd) 77int drm_tegra_new(struct drm_tegra **drmp, int fd)
79{ 78{
80 bool supported = false; 79 bool supported = false;
@@ -95,7 +94,6 @@ int drm_tegra_new(struct drm_tegra **drmp, int fd)
95 return drm_tegra_wrap(drmp, fd, false); 94 return drm_tegra_wrap(drmp, fd, false);
96} 95}
97 96
98drm_public
99void drm_tegra_close(struct drm_tegra *drm) 97void drm_tegra_close(struct drm_tegra *drm)
100{ 98{
101 if (!drm) 99 if (!drm)
@@ -107,7 +105,6 @@ void drm_tegra_close(struct drm_tegra *drm)
107 free(drm); 105 free(drm);
108} 106}
109 107
110drm_public
111int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm, 108int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
112 uint32_t flags, uint32_t size) 109 uint32_t flags, uint32_t size)
113{ 110{
@@ -146,7 +143,6 @@ int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm,
146 return 0; 143 return 0;
147} 144}
148 145
149drm_public
150int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm, 146int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
151 uint32_t handle, uint32_t flags, uint32_t size) 147 uint32_t handle, uint32_t flags, uint32_t size)
152{ 148{
@@ -170,7 +166,6 @@ int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm,
170 return 0; 166 return 0;
171} 167}
172 168
173drm_public
174int drm_tegra_bo_name_ref(struct drm_tegra *drm, uint32_t name, uint32_t size, 169int drm_tegra_bo_name_ref(struct drm_tegra *drm, uint32_t name, uint32_t size,
175 struct drm_tegra_bo **bop) 170 struct drm_tegra_bo **bop)
176{ 171{
@@ -203,7 +198,6 @@ err:
203 return ret; 198 return ret;
204} 199}
205 200
206drm_public
207int drm_tegra_bo_name_get(struct drm_tegra_bo *bo, uint32_t *name) 201int drm_tegra_bo_name_get(struct drm_tegra_bo *bo, uint32_t *name)
208{ 202{
209 struct drm_gem_flink args; 203 struct drm_gem_flink args;
@@ -227,7 +221,6 @@ int drm_tegra_bo_name_get(struct drm_tegra_bo *bo, uint32_t *name)
227 return 0; 221 return 0;
228} 222}
229 223
230drm_public
231struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo) 224struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo)
232{ 225{
233 if (bo) 226 if (bo)
@@ -236,14 +229,12 @@ struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo)
236 return bo; 229 return bo;
237} 230}
238 231
239drm_public
240void drm_tegra_bo_unref(struct drm_tegra_bo *bo) 232void drm_tegra_bo_unref(struct drm_tegra_bo *bo)
241{ 233{
242 if (bo && atomic_dec_and_test(&bo->ref)) 234 if (bo && atomic_dec_and_test(&bo->ref))
243 drm_tegra_bo_free(bo); 235 drm_tegra_bo_free(bo);
244} 236}
245 237
246drm_public
247int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle) 238int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle)
248{ 239{
249 if (!bo || !handle) 240 if (!bo || !handle)
@@ -254,7 +245,6 @@ int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle)
254 return 0; 245 return 0;
255} 246}
256 247
257drm_public
258int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr) 248int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr)
259{ 249{
260 struct drm_tegra *drm = bo->drm; 250 struct drm_tegra *drm = bo->drm;
@@ -287,7 +277,6 @@ int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr)
287 return 0; 277 return 0;
288} 278}
289 279
290drm_public
291int drm_tegra_bo_unmap(struct drm_tegra_bo *bo) 280int drm_tegra_bo_unmap(struct drm_tegra_bo *bo)
292{ 281{
293 if (!bo) 282 if (!bo)
@@ -304,7 +293,6 @@ int drm_tegra_bo_unmap(struct drm_tegra_bo *bo)
304 return 0; 293 return 0;
305} 294}
306 295
307drm_public
308int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags) 296int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags)
309{ 297{
310 struct drm_tegra_gem_get_flags args; 298 struct drm_tegra_gem_get_flags args;
@@ -328,7 +316,6 @@ int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags)
328 return 0; 316 return 0;
329} 317}
330 318
331drm_public
332int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags) 319int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags)
333{ 320{
334 struct drm_tegra_gem_get_flags args; 321 struct drm_tegra_gem_get_flags args;
@@ -350,7 +337,6 @@ int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags)
350 return 0; 337 return 0;
351} 338}
352 339
353drm_public
354int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo, 340int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo,
355 struct drm_tegra_bo_tiling *tiling) 341 struct drm_tegra_bo_tiling *tiling)
356{ 342{
@@ -377,7 +363,6 @@ int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo,
377 return 0; 363 return 0;
378} 364}
379 365
380drm_public
381int drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo, 366int drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo,
382 const struct drm_tegra_bo_tiling *tiling) 367 const struct drm_tegra_bo_tiling *tiling)
383{ 368{
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 00000000..5053e7d6
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1 @@
include $(call all-subdir-makefiles)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0904f30e..d8925764 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,25 +1,19 @@
1NULL:=# 1SUBDIRS = util kms modeprint proptest modetest vbltest
2
3AM_CPPFLAGS = \
4 -I $(top_srcdir)/include/drm \
5 -I $(top_srcdir)
6
7LDADD = $(top_builddir)/libdrm.la
8
9check_PROGRAMS = \
10 dristat \
11 drmstat
12
13SUBDIRS = modeprint proptest
14 2
15if HAVE_LIBKMS 3if HAVE_LIBKMS
16SUBDIRS += kmstest modetest planetest 4SUBDIRS += kmstest planetest
17endif 5endif
18 6
19if HAVE_RADEON 7if HAVE_RADEON
20SUBDIRS += radeon 8SUBDIRS += radeon
21endif 9endif
22 10
11if HAVE_AMDGPU
12if HAVE_CUNIT
13SUBDIRS += amdgpu
14endif
15endif
16
23if HAVE_EXYNOS 17if HAVE_EXYNOS
24SUBDIRS += exynos 18SUBDIRS += exynos
25endif 19endif
@@ -28,6 +22,29 @@ if HAVE_TEGRA
28SUBDIRS += tegra 22SUBDIRS += tegra
29endif 23endif
30 24
25AM_CFLAGS = \
26 $(WARN_CFLAGS)\
27 -I $(top_srcdir)/include/drm \
28 -I $(top_srcdir)
29
30LDADD = $(top_builddir)/libdrm.la
31
32check_PROGRAMS = \
33 dristat \
34 drmdevice \
35 drmstat
36
37dristat_LDADD = -lm
38
39if HAVE_NOUVEAU
40SUBDIRS += nouveau
41endif
42
43TESTS = \
44 drmsl \
45 hash \
46 random
47
31if HAVE_LIBUDEV 48if HAVE_LIBUDEV
32 49
33check_LTLIBRARIES = libdrmtest.la 50check_LTLIBRARIES = libdrmtest.la
@@ -36,37 +53,23 @@ libdrmtest_la_SOURCES = \
36 drmtest.c \ 53 drmtest.c \
37 drmtest.h 54 drmtest.h
38 55
39libdrmtest_la_LIBADD = \ 56LDADD += \
40 $(top_builddir)/libdrm.la \ 57 libdrmtest.la \
41 $(LIBUDEV_LIBS) 58 $(LIBUDEV_LIBS)
42 59
43LDADD += libdrmtest.la
44 60
45XFAIL_TESTS = \ 61XFAIL_TESTS = \
46 auth \ 62 auth \
47 lock 63 lock
48 64
49TESTS = \ 65TESTS += \
50 openclose \ 66 openclose \
51 getversion \ 67 getversion \
52 getclient \ 68 getclient \
53 getstats \ 69 getstats \
54 setversion \ 70 setversion \
55 updatedraw \ 71 updatedraw \
56 name_from_fd \ 72 name_from_fd
57 $(NULL)
58
59SUBDIRS += vbltest $(NULL)
60
61if HAVE_INTEL
62TESTS += \
63 gem_basic \
64 gem_flink \
65 gem_readwrite \
66 gem_mmap \
67 $(NULL)
68endif 73endif
69 74
70check_PROGRAMS += $(TESTS) 75check_PROGRAMS += $(TESTS)
71
72endif
diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
new file mode 100644
index 00000000..c1c3a32e
--- /dev/null
+++ b/tests/amdgpu/Makefile.am
@@ -0,0 +1,29 @@
1AM_CFLAGS = \
2 -I $(top_srcdir)/include/drm \
3 -I $(top_srcdir)/amdgpu \
4 -I $(top_srcdir)
5
6LDADD = $(top_builddir)/libdrm.la \
7 $(top_builddir)/amdgpu/libdrm_amdgpu.la \
8 $(CUNIT_LIBS)
9
10if HAVE_INSTALL_TESTS
11bin_PROGRAMS = \
12 amdgpu_test
13else
14noinst_PROGRAMS = \
15 amdgpu_test
16endif
17
18amdgpu_test_CPPFLAGS = $(CUNIT_CFLAGS)
19
20amdgpu_test_SOURCES = \
21 amdgpu_test.c \
22 amdgpu_test.h \
23 basic_tests.c \
24 bo_tests.c \
25 cs_tests.c \
26 uvd_messages.h \
27 vce_tests.c \
28 vce_ib.h \
29 frame.h
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
new file mode 100644
index 00000000..71f357c6
--- /dev/null
+++ b/tests/amdgpu/amdgpu_test.c
@@ -0,0 +1,243 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <string.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <string.h>
33#include <ctype.h>
34#include <fcntl.h>
35#include <errno.h>
36#include <signal.h>
37#include <time.h>
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <sys/ioctl.h>
41#include <sys/time.h>
42#include <stdarg.h>
43#include <stdint.h>
44
45#include "drm.h"
46#include "xf86drmMode.h"
47#include "xf86drm.h"
48
49#include "CUnit/Basic.h"
50
51#include "amdgpu_test.h"
52
53/**
54 * Open handles for amdgpu devices
55 *
56 */
57int drm_amdgpu[MAX_CARDS_SUPPORTED];
58
59/** The table of all known test suites to run */
60static CU_SuiteInfo suites[] = {
61 {
62 .pName = "Basic Tests",
63 .pInitFunc = suite_basic_tests_init,
64 .pCleanupFunc = suite_basic_tests_clean,
65 .pTests = basic_tests,
66 },
67 {
68 .pName = "BO Tests",
69 .pInitFunc = suite_bo_tests_init,
70 .pCleanupFunc = suite_bo_tests_clean,
71 .pTests = bo_tests,
72 },
73 {
74 .pName = "CS Tests",
75 .pInitFunc = suite_cs_tests_init,
76 .pCleanupFunc = suite_cs_tests_clean,
77 .pTests = cs_tests,
78 },
79 {
80 .pName = "VCE Tests",
81 .pInitFunc = suite_vce_tests_init,
82 .pCleanupFunc = suite_vce_tests_clean,
83 .pTests = vce_tests,
84 },
85 CU_SUITE_INFO_NULL,
86};
87
88
89/** Display information about all suites and their tests */
90static void display_test_suites(void)
91{
92 int iSuite;
93 int iTest;
94
95 printf("Suites\n");
96
97 for (iSuite = 0; suites[iSuite].pName != NULL; iSuite++) {
98 printf("Suite id = %d: Name '%s'\n",
99 iSuite + 1, suites[iSuite].pName);
100
101 for (iTest = 0; suites[iSuite].pTests[iTest].pName != NULL;
102 iTest++) {
103 printf(" Test id %d: Name: '%s'\n", iTest + 1,
104 suites[iSuite].pTests[iTest].pName);
105 }
106 }
107}
108
109
110/** Help string for command line parameters */
111static const char usage[] = "Usage: %s [-hl] [<-s <suite id>> [-t <test id>]]\n"
112 "where:\n"
113 " l - Display all suites and their tests\n"
114 " h - Display this help\n";
115/** Specified options strings for getopt */
116static const char options[] = "hls:t:";
117
118/* The main() function for setting up and running the tests.
119 * Returns a CUE_SUCCESS on successful running, another
120 * CUnit error code on failure.
121 */
122int main(int argc, char **argv)
123{
124 int c; /* Character received from getopt */
125 int i = 0;
126 int suite_id = -1; /* By default run everything */
127 int test_id = -1; /* By default run all tests in the suite */
128 CU_pSuite pSuite = NULL;
129 CU_pTest pTest = NULL;
130
131 int aval = drmAvailable();
132
133 if (aval == 0) {
134 fprintf(stderr, "DRM driver is not available\n");
135 exit(EXIT_FAILURE);
136 }
137
138
139 for (i = 0; i < MAX_CARDS_SUPPORTED; i++)
140 drm_amdgpu[i] = -1;
141
142
143 /* Parse command line string */
144 opterr = 0; /* Do not print error messages from getopt */
145 while ((c = getopt(argc, argv, options)) != -1) {
146 switch (c) {
147 case 'l':
148 display_test_suites();
149 exit(EXIT_SUCCESS);
150 case 's':
151 suite_id = atoi(optarg);
152 break;
153 case 't':
154 test_id = atoi(optarg);
155 break;
156 case '?':
157 case 'h':
158 fprintf(stderr, usage, argv[0]);
159 exit(EXIT_SUCCESS);
160 default:
161 fprintf(stderr, usage, argv[0]);
162 exit(EXIT_FAILURE);
163 }
164 }
165
166 /* Try to open all possible radeon connections
167 * Right now: Open only the 0.
168 */
169 printf("Try to open the card 0..\n");
170 drm_amdgpu[0] = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
171
172 if (drm_amdgpu[0] < 0) {
173 perror("Cannot open /dev/dri/card0\n");
174 exit(EXIT_FAILURE);
175 }
176
177 /** Display version of DRM driver */
178 drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]);
179
180 if (retval == NULL) {
181 perror("Could not get information about DRM driver");
182 exit(EXIT_FAILURE);
183 }
184
185 printf("DRM Driver: Name: [%s] : Date [%s] : Description [%s]\n",
186 retval->name, retval->date, retval->desc);
187
188 drmFreeVersion(retval);
189
190 /* Initialize test suites to run */
191
192 /* initialize the CUnit test registry */
193 if (CUE_SUCCESS != CU_initialize_registry()) {
194 close(drm_amdgpu[0]);
195 return CU_get_error();
196 }
197
198 /* Register suites. */
199 if (CU_register_suites(suites) != CUE_SUCCESS) {
200 fprintf(stderr, "suite registration failed - %s\n",
201 CU_get_error_msg());
202 CU_cleanup_registry();
203 close(drm_amdgpu[0]);
204 exit(EXIT_FAILURE);
205 }
206
207 /* Run tests using the CUnit Basic interface */
208 CU_basic_set_mode(CU_BRM_VERBOSE);
209
210 if (suite_id != -1) { /* If user specify particular suite? */
211 pSuite = CU_get_suite_by_index((unsigned int) suite_id,
212 CU_get_registry());
213
214 if (pSuite) {
215 if (test_id != -1) { /* If user specify test id */
216 pTest = CU_get_test_by_index(
217 (unsigned int) test_id,
218 pSuite);
219 if (pTest)
220 CU_basic_run_test(pSuite, pTest);
221 else {
222 fprintf(stderr, "Invalid test id: %d\n",
223 test_id);
224 CU_cleanup_registry();
225 close(drm_amdgpu[0]);
226 exit(EXIT_FAILURE);
227 }
228 } else
229 CU_basic_run_suite(pSuite);
230 } else {
231 fprintf(stderr, "Invalid suite id : %d\n",
232 suite_id);
233 CU_cleanup_registry();
234 close(drm_amdgpu[0]);
235 exit(EXIT_FAILURE);
236 }
237 } else
238 CU_basic_run_tests();
239
240 CU_cleanup_registry();
241 close(drm_amdgpu[0]);
242 return CU_get_error();
243}
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
new file mode 100644
index 00000000..fca92ad0
--- /dev/null
+++ b/tests/amdgpu/amdgpu_test.h
@@ -0,0 +1,236 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifndef _AMDGPU_TEST_H_
25#define _AMDGPU_TEST_H_
26
27#include "amdgpu.h"
28#include "amdgpu_drm.h"
29
30/**
31 * Define max. number of card in system which we are able to handle
32 */
33#define MAX_CARDS_SUPPORTED 4
34
35/* Forward reference for array to keep "drm" handles */
36extern int drm_amdgpu[MAX_CARDS_SUPPORTED];
37
38/************************* Basic test suite ********************************/
39
40/*
41 * Define basic test suite to serve as the starting point for future testing
42*/
43
44/**
45 * Initialize basic test suite
46 */
47int suite_basic_tests_init();
48
49/**
50 * Deinitialize basic test suite
51 */
52int suite_basic_tests_clean();
53
54/**
55 * Tests in basic test suite
56 */
57extern CU_TestInfo basic_tests[];
58
59/**
60 * Initialize bo test suite
61 */
62int suite_bo_tests_init();
63
64/**
65 * Deinitialize bo test suite
66 */
67int suite_bo_tests_clean();
68
69/**
70 * Tests in bo test suite
71 */
72extern CU_TestInfo bo_tests[];
73
74/**
75 * Initialize cs test suite
76 */
77int suite_cs_tests_init();
78
79/**
80 * Deinitialize cs test suite
81 */
82int suite_cs_tests_clean();
83
84/**
85 * Tests in cs test suite
86 */
87extern CU_TestInfo cs_tests[];
88
89/**
90 * Initialize vce test suite
91 */
92int suite_vce_tests_init();
93
94/**
95 * Deinitialize vce test suite
96 */
97int suite_vce_tests_clean();
98
99/**
100 * Tests in vce test suite
101 */
102extern CU_TestInfo vce_tests[];
103
104/**
105 * Helper functions
106 */
107static inline amdgpu_bo_handle gpu_mem_alloc(
108 amdgpu_device_handle device_handle,
109 uint64_t size,
110 uint64_t alignment,
111 uint32_t type,
112 uint64_t flags,
113 uint64_t *vmc_addr,
114 amdgpu_va_handle *va_handle)
115{
116 struct amdgpu_bo_alloc_request req = {0};
117 amdgpu_bo_handle buf_handle;
118 int r;
119
120 CU_ASSERT_NOT_EQUAL(vmc_addr, NULL);
121
122 req.alloc_size = size;
123 req.phys_alignment = alignment;
124 req.preferred_heap = type;
125 req.flags = flags;
126
127 r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
128 CU_ASSERT_EQUAL(r, 0);
129
130 r = amdgpu_va_range_alloc(device_handle,
131 amdgpu_gpu_va_range_general,
132 size, alignment, 0, vmc_addr,
133 va_handle, 0);
134 CU_ASSERT_EQUAL(r, 0);
135
136 r = amdgpu_bo_va_op(buf_handle, 0, size, *vmc_addr, 0, AMDGPU_VA_OP_MAP);
137 CU_ASSERT_EQUAL(r, 0);
138
139 return buf_handle;
140}
141
142static inline int gpu_mem_free(amdgpu_bo_handle bo,
143 amdgpu_va_handle va_handle,
144 uint64_t vmc_addr,
145 uint64_t size)
146{
147 int r;
148
149 r = amdgpu_bo_va_op(bo, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
150 CU_ASSERT_EQUAL(r, 0);
151
152 r = amdgpu_va_range_free(va_handle);
153 CU_ASSERT_EQUAL(r, 0);
154
155 r = amdgpu_bo_free(bo);
156 CU_ASSERT_EQUAL(r, 0);
157
158 return 0;
159}
160
161static inline int
162amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,
163 unsigned alignment, unsigned heap, uint64_t flags,
164 amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address,
165 amdgpu_va_handle *va_handle)
166{
167 struct amdgpu_bo_alloc_request request = {};
168 amdgpu_bo_handle buf_handle;
169 amdgpu_va_handle handle;
170 uint64_t vmc_addr;
171 int r;
172
173 request.alloc_size = size;
174 request.phys_alignment = alignment;
175 request.preferred_heap = heap;
176 request.flags = flags;
177
178 r = amdgpu_bo_alloc(dev, &request, &buf_handle);
179 if (r)
180 return r;
181
182 r = amdgpu_va_range_alloc(dev,
183 amdgpu_gpu_va_range_general,
184 size, alignment, 0, &vmc_addr,
185 &handle, 0);
186 if (r)
187 goto error_va_alloc;
188
189 r = amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_MAP);
190 if (r)
191 goto error_va_map;
192
193 r = amdgpu_bo_cpu_map(buf_handle, cpu);
194 if (r)
195 goto error_cpu_map;
196
197 *bo = buf_handle;
198 *mc_address = vmc_addr;
199 *va_handle = handle;
200
201 return 0;
202
203error_cpu_map:
204 amdgpu_bo_cpu_unmap(buf_handle);
205
206error_va_map:
207 amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);
208
209error_va_alloc:
210 amdgpu_bo_free(buf_handle);
211 return r;
212}
213
214static inline int
215amdgpu_bo_unmap_and_free(amdgpu_bo_handle bo, amdgpu_va_handle va_handle,
216 uint64_t mc_addr, uint64_t size)
217{
218 amdgpu_bo_cpu_unmap(bo);
219 amdgpu_bo_va_op(bo, 0, size, mc_addr, 0, AMDGPU_VA_OP_UNMAP);
220 amdgpu_va_range_free(va_handle);
221 amdgpu_bo_free(bo);
222
223 return 0;
224
225}
226
227static inline int
228amdgpu_get_bo_list(amdgpu_device_handle dev, amdgpu_bo_handle bo1,
229 amdgpu_bo_handle bo2, amdgpu_bo_list_handle *list)
230{
231 amdgpu_bo_handle resources[] = {bo1, bo2};
232
233 return amdgpu_bo_list_create(dev, bo2 ? 2 : 1, resources, NULL, list);
234}
235
236#endif /* #ifdef _AMDGPU_TEST_H_ */
diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c
new file mode 100644
index 00000000..e489e6e8
--- /dev/null
+++ b/tests/amdgpu/basic_tests.c
@@ -0,0 +1,846 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <unistd.h>
31#ifdef HAVE_ALLOCA_H
32# include <alloca.h>
33#endif
34
35#include "CUnit/Basic.h"
36
37#include "amdgpu_test.h"
38#include "amdgpu_drm.h"
39
40static amdgpu_device_handle device_handle;
41static uint32_t major_version;
42static uint32_t minor_version;
43
44static void amdgpu_query_info_test(void);
45static void amdgpu_memory_alloc(void);
46static void amdgpu_command_submission_gfx(void);
47static void amdgpu_command_submission_compute(void);
48static void amdgpu_command_submission_sdma(void);
49static void amdgpu_userptr_test(void);
50
51CU_TestInfo basic_tests[] = {
52 { "Query Info Test", amdgpu_query_info_test },
53 { "Memory alloc Test", amdgpu_memory_alloc },
54 { "Userptr Test", amdgpu_userptr_test },
55 { "Command submission Test (GFX)", amdgpu_command_submission_gfx },
56 { "Command submission Test (Compute)", amdgpu_command_submission_compute },
57 { "Command submission Test (SDMA)", amdgpu_command_submission_sdma },
58 CU_TEST_INFO_NULL,
59};
60#define BUFFER_SIZE (8 * 1024)
61#define SDMA_PKT_HEADER_op_offset 0
62#define SDMA_PKT_HEADER_op_mask 0x000000FF
63#define SDMA_PKT_HEADER_op_shift 0
64#define SDMA_PKT_HEADER_OP(x) (((x) & SDMA_PKT_HEADER_op_mask) << SDMA_PKT_HEADER_op_shift)
65#define SDMA_OPCODE_CONSTANT_FILL 11
66# define SDMA_CONSTANT_FILL_EXTRA_SIZE(x) ((x) << 14)
67 /* 0 = byte fill
68 * 2 = DW fill
69 */
70#define SDMA_PACKET(op, sub_op, e) ((((e) & 0xFFFF) << 16) | \
71 (((sub_op) & 0xFF) << 8) | \
72 (((op) & 0xFF) << 0))
73#define SDMA_OPCODE_WRITE 2
74# define SDMA_WRITE_SUB_OPCODE_LINEAR 0
75# define SDMA_WRTIE_SUB_OPCODE_TILED 1
76
77#define SDMA_OPCODE_COPY 1
78# define SDMA_COPY_SUB_OPCODE_LINEAR 0
79
80int suite_basic_tests_init(void)
81{
82 int r;
83
84 r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
85 &minor_version, &device_handle);
86
87 if (r == 0)
88 return CUE_SUCCESS;
89 else
90 return CUE_SINIT_FAILED;
91}
92
93int suite_basic_tests_clean(void)
94{
95 int r = amdgpu_device_deinitialize(device_handle);
96
97 if (r == 0)
98 return CUE_SUCCESS;
99 else
100 return CUE_SCLEAN_FAILED;
101}
102
103static void amdgpu_query_info_test(void)
104{
105 struct amdgpu_gpu_info gpu_info = {0};
106 uint32_t version, feature;
107 int r;
108
109 r = amdgpu_query_gpu_info(device_handle, &gpu_info);
110 CU_ASSERT_EQUAL(r, 0);
111
112 r = amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0,
113 0, &version, &feature);
114 CU_ASSERT_EQUAL(r, 0);
115}
116
117static void amdgpu_memory_alloc(void)
118{
119 amdgpu_bo_handle bo;
120 amdgpu_va_handle va_handle;
121 uint64_t bo_mc;
122 int r;
123
124 /* Test visible VRAM */
125 bo = gpu_mem_alloc(device_handle,
126 4096, 4096,
127 AMDGPU_GEM_DOMAIN_VRAM,
128 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
129 &bo_mc, &va_handle);
130
131 r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
132 CU_ASSERT_EQUAL(r, 0);
133
134 /* Test invisible VRAM */
135 bo = gpu_mem_alloc(device_handle,
136 4096, 4096,
137 AMDGPU_GEM_DOMAIN_VRAM,
138 AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
139 &bo_mc, &va_handle);
140
141 r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
142 CU_ASSERT_EQUAL(r, 0);
143
144 /* Test GART Cacheable */
145 bo = gpu_mem_alloc(device_handle,
146 4096, 4096,
147 AMDGPU_GEM_DOMAIN_GTT,
148 0, &bo_mc, &va_handle);
149
150 r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
151 CU_ASSERT_EQUAL(r, 0);
152
153 /* Test GART USWC */
154 bo = gpu_mem_alloc(device_handle,
155 4096, 4096,
156 AMDGPU_GEM_DOMAIN_GTT,
157 AMDGPU_GEM_CREATE_CPU_GTT_USWC,
158 &bo_mc, &va_handle);
159
160 r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
161 CU_ASSERT_EQUAL(r, 0);
162}
163
164static void amdgpu_command_submission_gfx_separate_ibs(void)
165{
166 amdgpu_context_handle context_handle;
167 amdgpu_bo_handle ib_result_handle, ib_result_ce_handle;
168 void *ib_result_cpu, *ib_result_ce_cpu;
169 uint64_t ib_result_mc_address, ib_result_ce_mc_address;
170 struct amdgpu_cs_request ibs_request = {0};
171 struct amdgpu_cs_ib_info ib_info[2];
172 struct amdgpu_cs_fence fence_status = {0};
173 uint32_t *ptr;
174 uint32_t expired;
175 amdgpu_bo_list_handle bo_list;
176 amdgpu_va_handle va_handle, va_handle_ce;
177 int r;
178
179 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
180 CU_ASSERT_EQUAL(r, 0);
181
182 r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
183 AMDGPU_GEM_DOMAIN_GTT, 0,
184 &ib_result_handle, &ib_result_cpu,
185 &ib_result_mc_address, &va_handle);
186 CU_ASSERT_EQUAL(r, 0);
187
188 r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
189 AMDGPU_GEM_DOMAIN_GTT, 0,
190 &ib_result_ce_handle, &ib_result_ce_cpu,
191 &ib_result_ce_mc_address, &va_handle_ce);
192 CU_ASSERT_EQUAL(r, 0);
193
194 r = amdgpu_get_bo_list(device_handle, ib_result_handle,
195 ib_result_ce_handle, &bo_list);
196 CU_ASSERT_EQUAL(r, 0);
197
198 memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
199
200 /* IT_SET_CE_DE_COUNTERS */
201 ptr = ib_result_ce_cpu;
202 ptr[0] = 0xc0008900;
203 ptr[1] = 0;
204 ptr[2] = 0xc0008400;
205 ptr[3] = 1;
206 ib_info[0].ib_mc_address = ib_result_ce_mc_address;
207 ib_info[0].size = 4;
208 ib_info[0].flags = AMDGPU_IB_FLAG_CE;
209
210 /* IT_WAIT_ON_CE_COUNTER */
211 ptr = ib_result_cpu;
212 ptr[0] = 0xc0008600;
213 ptr[1] = 0x00000001;
214 ib_info[1].ib_mc_address = ib_result_mc_address;
215 ib_info[1].size = 2;
216
217 ibs_request.ip_type = AMDGPU_HW_IP_GFX;
218 ibs_request.number_of_ibs = 2;
219 ibs_request.ibs = ib_info;
220 ibs_request.resources = bo_list;
221 ibs_request.fence_info.handle = NULL;
222
223 r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
224
225 CU_ASSERT_EQUAL(r, 0);
226
227 fence_status.context = context_handle;
228 fence_status.ip_type = AMDGPU_HW_IP_GFX;
229 fence_status.fence = ibs_request.seq_no;
230
231 r = amdgpu_cs_query_fence_status(&fence_status,
232 AMDGPU_TIMEOUT_INFINITE,
233 0, &expired);
234 CU_ASSERT_EQUAL(r, 0);
235
236 r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
237 ib_result_mc_address, 4096);
238 CU_ASSERT_EQUAL(r, 0);
239
240 r = amdgpu_bo_unmap_and_free(ib_result_ce_handle, va_handle_ce,
241 ib_result_ce_mc_address, 4096);
242 CU_ASSERT_EQUAL(r, 0);
243
244 r = amdgpu_bo_list_destroy(bo_list);
245 CU_ASSERT_EQUAL(r, 0);
246
247 r = amdgpu_cs_ctx_free(context_handle);
248 CU_ASSERT_EQUAL(r, 0);
249
250}
251
252static void amdgpu_command_submission_gfx_shared_ib(void)
253{
254 amdgpu_context_handle context_handle;
255 amdgpu_bo_handle ib_result_handle;
256 void *ib_result_cpu;
257 uint64_t ib_result_mc_address;
258 struct amdgpu_cs_request ibs_request = {0};
259 struct amdgpu_cs_ib_info ib_info[2];
260 struct amdgpu_cs_fence fence_status = {0};
261 uint32_t *ptr;
262 uint32_t expired;
263 amdgpu_bo_list_handle bo_list;
264 amdgpu_va_handle va_handle;
265 int r;
266
267 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
268 CU_ASSERT_EQUAL(r, 0);
269
270 r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
271 AMDGPU_GEM_DOMAIN_GTT, 0,
272 &ib_result_handle, &ib_result_cpu,
273 &ib_result_mc_address, &va_handle);
274 CU_ASSERT_EQUAL(r, 0);
275
276 r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
277 &bo_list);
278 CU_ASSERT_EQUAL(r, 0);
279
280 memset(ib_info, 0, 2 * sizeof(struct amdgpu_cs_ib_info));
281
282 /* IT_SET_CE_DE_COUNTERS */
283 ptr = ib_result_cpu;
284 ptr[0] = 0xc0008900;
285 ptr[1] = 0;
286 ptr[2] = 0xc0008400;
287 ptr[3] = 1;
288 ib_info[0].ib_mc_address = ib_result_mc_address;
289 ib_info[0].size = 4;
290 ib_info[0].flags = AMDGPU_IB_FLAG_CE;
291
292 ptr = (uint32_t *)ib_result_cpu + 4;
293 ptr[0] = 0xc0008600;
294 ptr[1] = 0x00000001;
295 ib_info[1].ib_mc_address = ib_result_mc_address + 16;
296 ib_info[1].size = 2;
297
298 ibs_request.ip_type = AMDGPU_HW_IP_GFX;
299 ibs_request.number_of_ibs = 2;
300 ibs_request.ibs = ib_info;
301 ibs_request.resources = bo_list;
302 ibs_request.fence_info.handle = NULL;
303
304 r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
305
306 CU_ASSERT_EQUAL(r, 0);
307
308 fence_status.context = context_handle;
309 fence_status.ip_type = AMDGPU_HW_IP_GFX;
310 fence_status.fence = ibs_request.seq_no;
311
312 r = amdgpu_cs_query_fence_status(&fence_status,
313 AMDGPU_TIMEOUT_INFINITE,
314 0, &expired);
315 CU_ASSERT_EQUAL(r, 0);
316
317 r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
318 ib_result_mc_address, 4096);
319 CU_ASSERT_EQUAL(r, 0);
320
321 r = amdgpu_bo_list_destroy(bo_list);
322 CU_ASSERT_EQUAL(r, 0);
323
324 r = amdgpu_cs_ctx_free(context_handle);
325 CU_ASSERT_EQUAL(r, 0);
326}
327
328static void amdgpu_command_submission_gfx(void)
329{
330 /* separate IB buffers for multi-IB submission */
331 amdgpu_command_submission_gfx_separate_ibs();
332 /* shared IB buffer for multi-IB submission */
333 amdgpu_command_submission_gfx_shared_ib();
334}
335
336static void amdgpu_command_submission_compute(void)
337{
338 amdgpu_context_handle context_handle;
339 amdgpu_bo_handle ib_result_handle;
340 void *ib_result_cpu;
341 uint64_t ib_result_mc_address;
342 struct amdgpu_cs_request ibs_request;
343 struct amdgpu_cs_ib_info ib_info;
344 struct amdgpu_cs_fence fence_status;
345 uint32_t *ptr;
346 uint32_t expired;
347 int i, r, instance;
348 amdgpu_bo_list_handle bo_list;
349 amdgpu_va_handle va_handle;
350
351 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
352 CU_ASSERT_EQUAL(r, 0);
353
354 for (instance = 0; instance < 8; instance++) {
355 r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
356 AMDGPU_GEM_DOMAIN_GTT, 0,
357 &ib_result_handle, &ib_result_cpu,
358 &ib_result_mc_address, &va_handle);
359 CU_ASSERT_EQUAL(r, 0);
360
361 r = amdgpu_get_bo_list(device_handle, ib_result_handle, NULL,
362 &bo_list);
363 CU_ASSERT_EQUAL(r, 0);
364
365 ptr = ib_result_cpu;
366 for (i = 0; i < 16; ++i)
367 ptr[i] = 0xffff1000;
368
369 memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info));
370 ib_info.ib_mc_address = ib_result_mc_address;
371 ib_info.size = 16;
372
373 memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
374 ibs_request.ip_type = AMDGPU_HW_IP_COMPUTE;
375 ibs_request.ring = instance;
376 ibs_request.number_of_ibs = 1;
377 ibs_request.ibs = &ib_info;
378 ibs_request.resources = bo_list;
379 ibs_request.fence_info.handle = NULL;
380
381 memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
382 r = amdgpu_cs_submit(context_handle, 0,&ibs_request, 1);
383 CU_ASSERT_EQUAL(r, 0);
384
385 fence_status.context = context_handle;
386 fence_status.ip_type = AMDGPU_HW_IP_COMPUTE;
387 fence_status.ring = instance;
388 fence_status.fence = ibs_request.seq_no;
389
390 r = amdgpu_cs_query_fence_status(&fence_status,
391 AMDGPU_TIMEOUT_INFINITE,
392 0, &expired);
393 CU_ASSERT_EQUAL(r, 0);
394
395 r = amdgpu_bo_list_destroy(bo_list);
396 CU_ASSERT_EQUAL(r, 0);
397
398 r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
399 ib_result_mc_address, 4096);
400 CU_ASSERT_EQUAL(r, 0);
401 }
402
403 r = amdgpu_cs_ctx_free(context_handle);
404 CU_ASSERT_EQUAL(r, 0);
405}
406
407/*
408 * caller need create/release:
409 * pm4_src, resources, ib_info, and ibs_request
410 * submit command stream described in ibs_request and wait for this IB accomplished
411 */
412static void amdgpu_sdma_test_exec_cs(amdgpu_context_handle context_handle,
413 int instance, int pm4_dw, uint32_t *pm4_src,
414 int res_cnt, amdgpu_bo_handle *resources,
415 struct amdgpu_cs_ib_info *ib_info,
416 struct amdgpu_cs_request *ibs_request)
417{
418 int r;
419 uint32_t expired;
420 uint32_t *ring_ptr;
421 amdgpu_bo_handle ib_result_handle;
422 void *ib_result_cpu;
423 uint64_t ib_result_mc_address;
424 struct amdgpu_cs_fence fence_status = {0};
425 amdgpu_bo_handle *all_res = alloca(sizeof(resources[0]) * (res_cnt + 1));
426 amdgpu_va_handle va_handle;
427
428 /* prepare CS */
429 CU_ASSERT_NOT_EQUAL(pm4_src, NULL);
430 CU_ASSERT_NOT_EQUAL(resources, NULL);
431 CU_ASSERT_NOT_EQUAL(ib_info, NULL);
432 CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
433 CU_ASSERT_TRUE(pm4_dw <= 1024);
434
435 /* allocate IB */
436 r = amdgpu_bo_alloc_and_map(device_handle, 4096, 4096,
437 AMDGPU_GEM_DOMAIN_GTT, 0,
438 &ib_result_handle, &ib_result_cpu,
439 &ib_result_mc_address, &va_handle);
440 CU_ASSERT_EQUAL(r, 0);
441
442 /* copy PM4 packet to ring from caller */
443 ring_ptr = ib_result_cpu;
444 memcpy(ring_ptr, pm4_src, pm4_dw * sizeof(*pm4_src));
445
446 ib_info->ib_mc_address = ib_result_mc_address;
447 ib_info->size = pm4_dw;
448
449 ibs_request->ip_type = AMDGPU_HW_IP_DMA;
450 ibs_request->ring = instance;
451 ibs_request->number_of_ibs = 1;
452 ibs_request->ibs = ib_info;
453 ibs_request->fence_info.handle = NULL;
454
455 memcpy(all_res, resources, sizeof(resources[0]) * res_cnt);
456 all_res[res_cnt] = ib_result_handle;
457
458 r = amdgpu_bo_list_create(device_handle, res_cnt+1, all_res,
459 NULL, &ibs_request->resources);
460 CU_ASSERT_EQUAL(r, 0);
461
462 CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
463
464 /* submit CS */
465 r = amdgpu_cs_submit(context_handle, 0, ibs_request, 1);
466 CU_ASSERT_EQUAL(r, 0);
467
468 r = amdgpu_bo_list_destroy(ibs_request->resources);
469 CU_ASSERT_EQUAL(r, 0);
470
471 fence_status.ip_type = AMDGPU_HW_IP_DMA;
472 fence_status.ring = ibs_request->ring;
473 fence_status.context = context_handle;
474 fence_status.fence = ibs_request->seq_no;
475
476 /* wait for IB accomplished */
477 r = amdgpu_cs_query_fence_status(&fence_status,
478 AMDGPU_TIMEOUT_INFINITE,
479 0, &expired);
480 CU_ASSERT_EQUAL(r, 0);
481 CU_ASSERT_EQUAL(expired, true);
482
483 r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle,
484 ib_result_mc_address, 4096);
485 CU_ASSERT_EQUAL(r, 0);
486}
487
488static void amdgpu_command_submission_sdma_write_linear(void)
489{
490 const int sdma_write_length = 128;
491 const int pm4_dw = 256;
492 amdgpu_context_handle context_handle;
493 amdgpu_bo_handle bo;
494 amdgpu_bo_handle *resources;
495 uint32_t *pm4;
496 struct amdgpu_cs_ib_info *ib_info;
497 struct amdgpu_cs_request *ibs_request;
498 uint64_t bo_mc;
499 volatile uint32_t *bo_cpu;
500 int i, j, r, loop;
501 uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
502 amdgpu_va_handle va_handle;
503
504 pm4 = calloc(pm4_dw, sizeof(*pm4));
505 CU_ASSERT_NOT_EQUAL(pm4, NULL);
506
507 ib_info = calloc(1, sizeof(*ib_info));
508 CU_ASSERT_NOT_EQUAL(ib_info, NULL);
509
510 ibs_request = calloc(1, sizeof(*ibs_request));
511 CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
512
513 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
514 CU_ASSERT_EQUAL(r, 0);
515
516 /* prepare resource */
517 resources = calloc(1, sizeof(amdgpu_bo_handle));
518 CU_ASSERT_NOT_EQUAL(resources, NULL);
519
520 loop = 0;
521 while(loop < 2) {
522 /* allocate UC bo for sDMA use */
523 r = amdgpu_bo_alloc_and_map(device_handle,
524 sdma_write_length * sizeof(uint32_t),
525 4096, AMDGPU_GEM_DOMAIN_GTT,
526 gtt_flags[loop], &bo, (void**)&bo_cpu,
527 &bo_mc, &va_handle);
528 CU_ASSERT_EQUAL(r, 0);
529
530 /* clear bo */
531 memset((void*)bo_cpu, 0, sdma_write_length * sizeof(uint32_t));
532
533
534 resources[0] = bo;
535
536 /* fullfill PM4: test DMA write-linear */
537 i = j = 0;
538 pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
539 SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
540 pm4[i++] = 0xffffffff & bo_mc;
541 pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
542 pm4[i++] = sdma_write_length;
543 while(j++ < sdma_write_length)
544 pm4[i++] = 0xdeadbeaf;
545
546 amdgpu_sdma_test_exec_cs(context_handle, 0,
547 i, pm4,
548 1, resources,
549 ib_info, ibs_request);
550
551 /* verify if SDMA test result meets with expected */
552 i = 0;
553 while(i < sdma_write_length) {
554 CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
555 }
556
557 r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
558 sdma_write_length * sizeof(uint32_t));
559 CU_ASSERT_EQUAL(r, 0);
560 loop++;
561 }
562 /* clean resources */
563 free(resources);
564 free(ibs_request);
565 free(ib_info);
566 free(pm4);
567
568 /* end of test */
569 r = amdgpu_cs_ctx_free(context_handle);
570 CU_ASSERT_EQUAL(r, 0);
571}
572
573static void amdgpu_command_submission_sdma_const_fill(void)
574{
575 const int sdma_write_length = 1024 * 1024;
576 const int pm4_dw = 256;
577 amdgpu_context_handle context_handle;
578 amdgpu_bo_handle bo;
579 amdgpu_bo_handle *resources;
580 uint32_t *pm4;
581 struct amdgpu_cs_ib_info *ib_info;
582 struct amdgpu_cs_request *ibs_request;
583 uint64_t bo_mc;
584 volatile uint32_t *bo_cpu;
585 int i, j, r, loop;
586 uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
587 amdgpu_va_handle va_handle;
588
589 pm4 = calloc(pm4_dw, sizeof(*pm4));
590 CU_ASSERT_NOT_EQUAL(pm4, NULL);
591
592 ib_info = calloc(1, sizeof(*ib_info));
593 CU_ASSERT_NOT_EQUAL(ib_info, NULL);
594
595 ibs_request = calloc(1, sizeof(*ibs_request));
596 CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
597
598 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
599 CU_ASSERT_EQUAL(r, 0);
600
601 /* prepare resource */
602 resources = calloc(1, sizeof(amdgpu_bo_handle));
603 CU_ASSERT_NOT_EQUAL(resources, NULL);
604
605 loop = 0;
606 while(loop < 2) {
607 /* allocate UC bo for sDMA use */
608 r = amdgpu_bo_alloc_and_map(device_handle,
609 sdma_write_length, 4096,
610 AMDGPU_GEM_DOMAIN_GTT,
611 gtt_flags[loop], &bo, (void**)&bo_cpu,
612 &bo_mc, &va_handle);
613 CU_ASSERT_EQUAL(r, 0);
614
615 /* clear bo */
616 memset((void*)bo_cpu, 0, sdma_write_length);
617
618 resources[0] = bo;
619
620 /* fullfill PM4: test DMA const fill */
621 i = j = 0;
622 pm4[i++] = SDMA_PACKET(SDMA_OPCODE_CONSTANT_FILL, 0,
623 SDMA_CONSTANT_FILL_EXTRA_SIZE(2));
624 pm4[i++] = 0xffffffff & bo_mc;
625 pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
626 pm4[i++] = 0xdeadbeaf;
627 pm4[i++] = sdma_write_length;
628
629 amdgpu_sdma_test_exec_cs(context_handle, 0,
630 i, pm4,
631 1, resources,
632 ib_info, ibs_request);
633
634 /* verify if SDMA test result meets with expected */
635 i = 0;
636 while(i < (sdma_write_length / 4)) {
637 CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
638 }
639
640 r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
641 sdma_write_length);
642 CU_ASSERT_EQUAL(r, 0);
643 loop++;
644 }
645 /* clean resources */
646 free(resources);
647 free(ibs_request);
648 free(ib_info);
649 free(pm4);
650
651 /* end of test */
652 r = amdgpu_cs_ctx_free(context_handle);
653 CU_ASSERT_EQUAL(r, 0);
654}
655
656static void amdgpu_command_submission_sdma_copy_linear(void)
657{
658 const int sdma_write_length = 1024;
659 const int pm4_dw = 256;
660 amdgpu_context_handle context_handle;
661 amdgpu_bo_handle bo1, bo2;
662 amdgpu_bo_handle *resources;
663 uint32_t *pm4;
664 struct amdgpu_cs_ib_info *ib_info;
665 struct amdgpu_cs_request *ibs_request;
666 uint64_t bo1_mc, bo2_mc;
667 volatile unsigned char *bo1_cpu, *bo2_cpu;
668 int i, j, r, loop1, loop2;
669 uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
670 amdgpu_va_handle bo1_va_handle, bo2_va_handle;
671
672 pm4 = calloc(pm4_dw, sizeof(*pm4));
673 CU_ASSERT_NOT_EQUAL(pm4, NULL);
674
675 ib_info = calloc(1, sizeof(*ib_info));
676 CU_ASSERT_NOT_EQUAL(ib_info, NULL);
677
678 ibs_request = calloc(1, sizeof(*ibs_request));
679 CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
680
681 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
682 CU_ASSERT_EQUAL(r, 0);
683
684 /* prepare resource */
685 resources = calloc(2, sizeof(amdgpu_bo_handle));
686 CU_ASSERT_NOT_EQUAL(resources, NULL);
687
688 loop1 = loop2 = 0;
689 /* run 9 circle to test all mapping combination */
690 while(loop1 < 2) {
691 while(loop2 < 2) {
692 /* allocate UC bo1for sDMA use */
693 r = amdgpu_bo_alloc_and_map(device_handle,
694 sdma_write_length, 4096,
695 AMDGPU_GEM_DOMAIN_GTT,
696 gtt_flags[loop1], &bo1,
697 (void**)&bo1_cpu, &bo1_mc,
698 &bo1_va_handle);
699 CU_ASSERT_EQUAL(r, 0);
700
701 /* set bo1 */
702 memset((void*)bo1_cpu, 0xaa, sdma_write_length);
703
704 /* allocate UC bo2 for sDMA use */
705 r = amdgpu_bo_alloc_and_map(device_handle,
706 sdma_write_length, 4096,
707 AMDGPU_GEM_DOMAIN_GTT,
708 gtt_flags[loop2], &bo2,
709 (void**)&bo2_cpu, &bo2_mc,
710 &bo2_va_handle);
711 CU_ASSERT_EQUAL(r, 0);
712
713 /* clear bo2 */
714 memset((void*)bo2_cpu, 0, sdma_write_length);
715
716 resources[0] = bo1;
717 resources[1] = bo2;
718
719 /* fullfill PM4: test DMA copy linear */
720 i = j = 0;
721 pm4[i++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
722 pm4[i++] = sdma_write_length;
723 pm4[i++] = 0;
724 pm4[i++] = 0xffffffff & bo1_mc;
725 pm4[i++] = (0xffffffff00000000 & bo1_mc) >> 32;
726 pm4[i++] = 0xffffffff & bo2_mc;
727 pm4[i++] = (0xffffffff00000000 & bo2_mc) >> 32;
728
729
730 amdgpu_sdma_test_exec_cs(context_handle, 0,
731 i, pm4,
732 2, resources,
733 ib_info, ibs_request);
734
735 /* verify if SDMA test result meets with expected */
736 i = 0;
737 while(i < sdma_write_length) {
738 CU_ASSERT_EQUAL(bo2_cpu[i++], 0xaa);
739 }
740 r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc,
741 sdma_write_length);
742 CU_ASSERT_EQUAL(r, 0);
743 r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc,
744 sdma_write_length);
745 CU_ASSERT_EQUAL(r, 0);
746 loop2++;
747 }
748 loop1++;
749 }
750 /* clean resources */
751 free(resources);
752 free(ibs_request);
753 free(ib_info);
754 free(pm4);
755
756 /* end of test */
757 r = amdgpu_cs_ctx_free(context_handle);
758 CU_ASSERT_EQUAL(r, 0);
759}
760
761static void amdgpu_command_submission_sdma(void)
762{
763 amdgpu_command_submission_sdma_write_linear();
764 amdgpu_command_submission_sdma_const_fill();
765 amdgpu_command_submission_sdma_copy_linear();
766}
767
768static void amdgpu_userptr_test(void)
769{
770 int i, r, j;
771 uint32_t *pm4 = NULL;
772 uint64_t bo_mc;
773 void *ptr = NULL;
774 int pm4_dw = 256;
775 int sdma_write_length = 4;
776 amdgpu_bo_handle handle;
777 amdgpu_context_handle context_handle;
778 struct amdgpu_cs_ib_info *ib_info;
779 struct amdgpu_cs_request *ibs_request;
780 amdgpu_bo_handle buf_handle;
781 amdgpu_va_handle va_handle;
782
783 pm4 = calloc(pm4_dw, sizeof(*pm4));
784 CU_ASSERT_NOT_EQUAL(pm4, NULL);
785
786 ib_info = calloc(1, sizeof(*ib_info));
787 CU_ASSERT_NOT_EQUAL(ib_info, NULL);
788
789 ibs_request = calloc(1, sizeof(*ibs_request));
790 CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
791
792 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
793 CU_ASSERT_EQUAL(r, 0);
794
795 posix_memalign(&ptr, sysconf(_SC_PAGE_SIZE), BUFFER_SIZE);
796 CU_ASSERT_NOT_EQUAL(ptr, NULL);
797 memset(ptr, 0, BUFFER_SIZE);
798
799 r = amdgpu_create_bo_from_user_mem(device_handle,
800 ptr, BUFFER_SIZE, &buf_handle);
801 CU_ASSERT_EQUAL(r, 0);
802
803 r = amdgpu_va_range_alloc(device_handle,
804 amdgpu_gpu_va_range_general,
805 BUFFER_SIZE, 1, 0, &bo_mc,
806 &va_handle, 0);
807 CU_ASSERT_EQUAL(r, 0);
808
809 r = amdgpu_bo_va_op(buf_handle, 0, BUFFER_SIZE, bo_mc, 0, AMDGPU_VA_OP_MAP);
810 CU_ASSERT_EQUAL(r, 0);
811
812 handle = buf_handle;
813
814 j = i = 0;
815 pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
816 SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
817 pm4[i++] = 0xffffffff & bo_mc;
818 pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
819 pm4[i++] = sdma_write_length;
820
821 while (j++ < sdma_write_length)
822 pm4[i++] = 0xdeadbeaf;
823
824 amdgpu_sdma_test_exec_cs(context_handle, 0,
825 i, pm4,
826 1, &handle,
827 ib_info, ibs_request);
828 i = 0;
829 while (i < sdma_write_length) {
830 CU_ASSERT_EQUAL(((int*)ptr)[i++], 0xdeadbeaf);
831 }
832 free(ibs_request);
833 free(ib_info);
834 free(pm4);
835
836 r = amdgpu_bo_va_op(buf_handle, 0, BUFFER_SIZE, bo_mc, 0, AMDGPU_VA_OP_UNMAP);
837 CU_ASSERT_EQUAL(r, 0);
838 r = amdgpu_va_range_free(va_handle);
839 CU_ASSERT_EQUAL(r, 0);
840 r = amdgpu_bo_free(buf_handle);
841 CU_ASSERT_EQUAL(r, 0);
842 free(ptr);
843
844 r = amdgpu_cs_ctx_free(context_handle);
845 CU_ASSERT_EQUAL(r, 0);
846}
diff --git a/tests/amdgpu/bo_tests.c b/tests/amdgpu/bo_tests.c
new file mode 100644
index 00000000..993895d8
--- /dev/null
+++ b/tests/amdgpu/bo_tests.c
@@ -0,0 +1,186 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <stdio.h>
29
30#include "CUnit/Basic.h"
31
32#include "amdgpu_test.h"
33#include "amdgpu_drm.h"
34
35#define BUFFER_SIZE (4*1024)
36#define BUFFER_ALIGN (4*1024)
37
38static amdgpu_device_handle device_handle;
39static uint32_t major_version;
40static uint32_t minor_version;
41
42static amdgpu_bo_handle buffer_handle;
43static uint64_t virtual_mc_base_address;
44static amdgpu_va_handle va_handle;
45
46static void amdgpu_bo_export_import(void);
47static void amdgpu_bo_metadata(void);
48static void amdgpu_bo_map_unmap(void);
49
50CU_TestInfo bo_tests[] = {
51 { "Export/Import", amdgpu_bo_export_import },
52#if 0
53 { "Metadata", amdgpu_bo_metadata },
54#endif
55 { "CPU map/unmap", amdgpu_bo_map_unmap },
56 CU_TEST_INFO_NULL,
57};
58
59int suite_bo_tests_init(void)
60{
61 struct amdgpu_bo_alloc_request req = {0};
62 amdgpu_bo_handle buf_handle;
63 uint64_t va;
64 int r;
65
66 r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
67 &minor_version, &device_handle);
68 if (r)
69 return CUE_SINIT_FAILED;
70
71 req.alloc_size = BUFFER_SIZE;
72 req.phys_alignment = BUFFER_ALIGN;
73 req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
74
75 r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
76 if (r)
77 return CUE_SINIT_FAILED;
78
79 r = amdgpu_va_range_alloc(device_handle,
80 amdgpu_gpu_va_range_general,
81 BUFFER_SIZE, BUFFER_ALIGN, 0,
82 &va, &va_handle, 0);
83 if (r)
84 goto error_va_alloc;
85
86 r = amdgpu_bo_va_op(buf_handle, 0, BUFFER_SIZE, va, 0, AMDGPU_VA_OP_MAP);
87 if (r)
88 goto error_va_map;
89
90 buffer_handle = buf_handle;
91 virtual_mc_base_address = va;
92
93 return CUE_SUCCESS;
94
95error_va_map:
96 amdgpu_va_range_free(va_handle);
97
98error_va_alloc:
99 amdgpu_bo_free(buf_handle);
100 return CUE_SINIT_FAILED;
101}
102
103int suite_bo_tests_clean(void)
104{
105 int r;
106
107 r = amdgpu_bo_va_op(buffer_handle, 0, BUFFER_SIZE,
108 virtual_mc_base_address, 0,
109 AMDGPU_VA_OP_UNMAP);
110 if (r)
111 return CUE_SCLEAN_FAILED;
112
113 r = amdgpu_va_range_free(va_handle);
114 if (r)
115 return CUE_SCLEAN_FAILED;
116
117 r = amdgpu_bo_free(buffer_handle);
118 if (r)
119 return CUE_SCLEAN_FAILED;
120
121 r = amdgpu_device_deinitialize(device_handle);
122 if (r)
123 return CUE_SCLEAN_FAILED;
124
125 return CUE_SUCCESS;
126}
127
128static void amdgpu_bo_export_import_do_type(enum amdgpu_bo_handle_type type)
129{
130 struct amdgpu_bo_import_result res = {0};
131 uint32_t shared_handle;
132 int r;
133
134 r = amdgpu_bo_export(buffer_handle, type, &shared_handle);
135 CU_ASSERT_EQUAL(r, 0);
136
137 r = amdgpu_bo_import(device_handle, type, shared_handle, &res);
138 CU_ASSERT_EQUAL(r, 0);
139
140 CU_ASSERT_EQUAL(res.buf_handle, buffer_handle);
141 CU_ASSERT_EQUAL(res.alloc_size, BUFFER_SIZE);
142
143 r = amdgpu_bo_free(res.buf_handle);
144 CU_ASSERT_EQUAL(r, 0);
145}
146
147static void amdgpu_bo_export_import(void)
148{
149 amdgpu_bo_export_import_do_type(amdgpu_bo_handle_type_gem_flink_name);
150 amdgpu_bo_export_import_do_type(amdgpu_bo_handle_type_dma_buf_fd);
151}
152
153static void amdgpu_bo_metadata(void)
154{
155 struct amdgpu_bo_metadata meta = {0};
156 struct amdgpu_bo_info info = {0};
157 int r;
158
159 meta.size_metadata = 1;
160 meta.umd_metadata[0] = 0xdeadbeef;
161
162 r = amdgpu_bo_set_metadata(buffer_handle, &meta);
163 CU_ASSERT_EQUAL(r, 0);
164
165 r = amdgpu_bo_query_info(buffer_handle, &info);
166 CU_ASSERT_EQUAL(r, 0);
167
168 CU_ASSERT_EQUAL(info.metadata.size_metadata, 1);
169 CU_ASSERT_EQUAL(info.metadata.umd_metadata[0], 0xdeadbeef);
170}
171
172static void amdgpu_bo_map_unmap(void)
173{
174 uint32_t *ptr;
175 int i, r;
176
177 r = amdgpu_bo_cpu_map(buffer_handle, (void **)&ptr);
178 CU_ASSERT_EQUAL(r, 0);
179 CU_ASSERT_NOT_EQUAL(ptr, NULL);
180
181 for (i = 0; i < (BUFFER_SIZE / 4); ++i)
182 ptr[i] = 0xdeadbeef;
183
184 r = amdgpu_bo_cpu_unmap(buffer_handle);
185 CU_ASSERT_EQUAL(r, 0);
186}
diff --git a/tests/amdgpu/cs_tests.c b/tests/amdgpu/cs_tests.c
new file mode 100644
index 00000000..dfbf5af9
--- /dev/null
+++ b/tests/amdgpu/cs_tests.c
@@ -0,0 +1,392 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <stdio.h>
29
30#include "CUnit/Basic.h"
31
32#include "util_math.h"
33
34#include "amdgpu_test.h"
35#include "uvd_messages.h"
36#include "amdgpu_drm.h"
37#include "amdgpu_internal.h"
38
39#define IB_SIZE 4096
40#define MAX_RESOURCES 16
41
42static amdgpu_device_handle device_handle;
43static uint32_t major_version;
44static uint32_t minor_version;
45static uint32_t family_id;
46
47static amdgpu_context_handle context_handle;
48static amdgpu_bo_handle ib_handle;
49static uint64_t ib_mc_address;
50static uint32_t *ib_cpu;
51static amdgpu_va_handle ib_va_handle;
52
53static amdgpu_bo_handle resources[MAX_RESOURCES];
54static unsigned num_resources;
55
56static void amdgpu_cs_uvd_create(void);
57static void amdgpu_cs_uvd_decode(void);
58static void amdgpu_cs_uvd_destroy(void);
59
60CU_TestInfo cs_tests[] = {
61 { "UVD create", amdgpu_cs_uvd_create },
62 { "UVD decode", amdgpu_cs_uvd_decode },
63 { "UVD destroy", amdgpu_cs_uvd_destroy },
64 CU_TEST_INFO_NULL,
65};
66
67int suite_cs_tests_init(void)
68{
69 amdgpu_bo_handle ib_result_handle;
70 void *ib_result_cpu;
71 uint64_t ib_result_mc_address;
72 amdgpu_va_handle ib_result_va_handle;
73 int r;
74
75 r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
76 &minor_version, &device_handle);
77 if (r)
78 return CUE_SINIT_FAILED;
79
80 family_id = device_handle->info.family_id;
81
82 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
83 if (r)
84 return CUE_SINIT_FAILED;
85
86 r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
87 AMDGPU_GEM_DOMAIN_GTT, 0,
88 &ib_result_handle, &ib_result_cpu,
89 &ib_result_mc_address,
90 &ib_result_va_handle);
91 if (r)
92 return CUE_SINIT_FAILED;
93
94 ib_handle = ib_result_handle;
95 ib_mc_address = ib_result_mc_address;
96 ib_cpu = ib_result_cpu;
97 ib_va_handle = ib_result_va_handle;
98
99 return CUE_SUCCESS;
100}
101
102int suite_cs_tests_clean(void)
103{
104 int r;
105
106 r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
107 ib_mc_address, IB_SIZE);
108 if (r)
109 return CUE_SCLEAN_FAILED;
110
111 r = amdgpu_cs_ctx_free(context_handle);
112 if (r)
113 return CUE_SCLEAN_FAILED;
114
115 r = amdgpu_device_deinitialize(device_handle);
116 if (r)
117 return CUE_SCLEAN_FAILED;
118
119 return CUE_SUCCESS;
120}
121
122static int submit(unsigned ndw, unsigned ip)
123{
124 struct amdgpu_cs_request ibs_request = {0};
125 struct amdgpu_cs_ib_info ib_info = {0};
126 struct amdgpu_cs_fence fence_status = {0};
127 uint32_t expired;
128 int r;
129
130 ib_info.ib_mc_address = ib_mc_address;
131 ib_info.size = ndw;
132
133 ibs_request.ip_type = ip;
134
135 r = amdgpu_bo_list_create(device_handle, num_resources, resources,
136 NULL, &ibs_request.resources);
137 if (r)
138 return r;
139
140 ibs_request.number_of_ibs = 1;
141 ibs_request.ibs = &ib_info;
142 ibs_request.fence_info.handle = NULL;
143
144 r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
145 if (r)
146 return r;
147
148 r = amdgpu_bo_list_destroy(ibs_request.resources);
149 if (r)
150 return r;
151
152 fence_status.context = context_handle;
153 fence_status.ip_type = ip;
154 fence_status.fence = ibs_request.seq_no;
155
156 r = amdgpu_cs_query_fence_status(&fence_status,
157 AMDGPU_TIMEOUT_INFINITE,
158 0, &expired);
159 if (r)
160 return r;
161
162 return 0;
163}
164
165static void uvd_cmd(uint64_t addr, unsigned cmd, int *idx)
166{
167 ib_cpu[(*idx)++] = 0x3BC4;
168 ib_cpu[(*idx)++] = addr;
169 ib_cpu[(*idx)++] = 0x3BC5;
170 ib_cpu[(*idx)++] = addr >> 32;
171 ib_cpu[(*idx)++] = 0x3BC3;
172 ib_cpu[(*idx)++] = cmd << 1;
173}
174
175static void amdgpu_cs_uvd_create(void)
176{
177 struct amdgpu_bo_alloc_request req = {0};
178 amdgpu_bo_handle buf_handle;
179 uint64_t va = 0;
180 amdgpu_va_handle va_handle;
181 void *msg;
182 int i, r;
183
184 req.alloc_size = 4*1024;
185 req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
186
187 r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
188 CU_ASSERT_EQUAL(r, 0);
189
190 r = amdgpu_va_range_alloc(device_handle,
191 amdgpu_gpu_va_range_general,
192 4096, 1, 0, &va,
193 &va_handle, 0);
194 CU_ASSERT_EQUAL(r, 0);
195
196 r = amdgpu_bo_va_op(buf_handle, 0, 4096, va, 0, AMDGPU_VA_OP_MAP);
197 CU_ASSERT_EQUAL(r, 0);
198
199 r = amdgpu_bo_cpu_map(buf_handle, &msg);
200 CU_ASSERT_EQUAL(r, 0);
201
202 memcpy(msg, uvd_create_msg, sizeof(uvd_create_msg));
203 if (family_id >= AMDGPU_FAMILY_VI)
204 ((uint8_t*)msg)[0x10] = 7;
205
206 r = amdgpu_bo_cpu_unmap(buf_handle);
207 CU_ASSERT_EQUAL(r, 0);
208
209 num_resources = 0;
210 resources[num_resources++] = buf_handle;
211 resources[num_resources++] = ib_handle;
212
213 i = 0;
214 uvd_cmd(va, 0x0, &i);
215 for (; i % 16; ++i)
216 ib_cpu[i] = 0x80000000;
217
218 r = submit(i, AMDGPU_HW_IP_UVD);
219 CU_ASSERT_EQUAL(r, 0);
220
221 r = amdgpu_bo_va_op(buf_handle, 0, 4096, va, 0, AMDGPU_VA_OP_UNMAP);
222 CU_ASSERT_EQUAL(r, 0);
223
224 r = amdgpu_va_range_free(va_handle);
225 CU_ASSERT_EQUAL(r, 0);
226
227 r = amdgpu_bo_free(buf_handle);
228 CU_ASSERT_EQUAL(r, 0);
229}
230
231static void amdgpu_cs_uvd_decode(void)
232{
233 const unsigned dpb_size = 15923584, dt_size = 737280;
234 uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, dt_addr, it_addr;
235 struct amdgpu_bo_alloc_request req = {0};
236 amdgpu_bo_handle buf_handle;
237 amdgpu_va_handle va_handle;
238 uint64_t va = 0;
239 uint64_t sum;
240 uint8_t *ptr;
241 int i, r;
242
243 req.alloc_size = 4*1024; /* msg */
244 req.alloc_size += 4*1024; /* fb */
245 if (family_id >= AMDGPU_FAMILY_VI)
246 req.alloc_size += 4096; /*it_scaling_table*/
247 req.alloc_size += ALIGN(sizeof(uvd_bitstream), 4*1024);
248 req.alloc_size += ALIGN(dpb_size, 4*1024);
249 req.alloc_size += ALIGN(dt_size, 4*1024);
250
251 req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
252
253 r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
254 CU_ASSERT_EQUAL(r, 0);
255
256 r = amdgpu_va_range_alloc(device_handle,
257 amdgpu_gpu_va_range_general,
258 req.alloc_size, 1, 0, &va,
259 &va_handle, 0);
260 CU_ASSERT_EQUAL(r, 0);
261
262 r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
263 AMDGPU_VA_OP_MAP);
264 CU_ASSERT_EQUAL(r, 0);
265
266 r = amdgpu_bo_cpu_map(buf_handle, (void **)&ptr);
267 CU_ASSERT_EQUAL(r, 0);
268
269 memcpy(ptr, uvd_decode_msg, sizeof(uvd_decode_msg));
270 if (family_id >= AMDGPU_FAMILY_VI)
271 ptr[0x10] = 7;
272
273 ptr += 4*1024;
274 memset(ptr, 0, 4*1024);
275 if (family_id >= AMDGPU_FAMILY_VI) {
276 ptr += 4*1024;
277 memcpy(ptr, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
278 }
279
280 ptr += 4*1024;
281 memcpy(ptr, uvd_bitstream, sizeof(uvd_bitstream));
282
283 ptr += ALIGN(sizeof(uvd_bitstream), 4*1024);
284 memset(ptr, 0, dpb_size);
285
286 ptr += ALIGN(dpb_size, 4*1024);
287 memset(ptr, 0, dt_size);
288
289 num_resources = 0;
290 resources[num_resources++] = buf_handle;
291 resources[num_resources++] = ib_handle;
292
293 msg_addr = va;
294 fb_addr = msg_addr + 4*1024;
295 if (family_id >= AMDGPU_FAMILY_VI) {
296 it_addr = fb_addr + 4*1024;
297 bs_addr = it_addr + 4*1024;
298 } else
299 bs_addr = fb_addr + 4*1024;
300 dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
301 dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
302
303 i = 0;
304 uvd_cmd(msg_addr, 0x0, &i);
305 uvd_cmd(dpb_addr, 0x1, &i);
306 uvd_cmd(dt_addr, 0x2, &i);
307 uvd_cmd(fb_addr, 0x3, &i);
308 uvd_cmd(bs_addr, 0x100, &i);
309 if (family_id >= AMDGPU_FAMILY_VI)
310 uvd_cmd(it_addr, 0x204, &i);
311 ib_cpu[i++] = 0x3BC6;
312 ib_cpu[i++] = 0x1;
313 for (; i % 16; ++i)
314 ib_cpu[i] = 0x80000000;
315
316 r = submit(i, AMDGPU_HW_IP_UVD);
317 CU_ASSERT_EQUAL(r, 0);
318
319 /* TODO: use a real CRC32 */
320 for (i = 0, sum = 0; i < dt_size; ++i)
321 sum += ptr[i];
322 CU_ASSERT_EQUAL(sum, 0x20345d8);
323
324 r = amdgpu_bo_cpu_unmap(buf_handle);
325 CU_ASSERT_EQUAL(r, 0);
326
327 r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_UNMAP);
328 CU_ASSERT_EQUAL(r, 0);
329
330 r = amdgpu_va_range_free(va_handle);
331 CU_ASSERT_EQUAL(r, 0);
332
333 r = amdgpu_bo_free(buf_handle);
334 CU_ASSERT_EQUAL(r, 0);
335}
336
337static void amdgpu_cs_uvd_destroy(void)
338{
339 struct amdgpu_bo_alloc_request req = {0};
340 amdgpu_bo_handle buf_handle;
341 amdgpu_va_handle va_handle;
342 uint64_t va = 0;
343 void *msg;
344 int i, r;
345
346 req.alloc_size = 4*1024;
347 req.preferred_heap = AMDGPU_GEM_DOMAIN_GTT;
348
349 r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
350 CU_ASSERT_EQUAL(r, 0);
351
352 r = amdgpu_va_range_alloc(device_handle,
353 amdgpu_gpu_va_range_general,
354 req.alloc_size, 1, 0, &va,
355 &va_handle, 0);
356 CU_ASSERT_EQUAL(r, 0);
357
358 r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
359 AMDGPU_VA_OP_MAP);
360 CU_ASSERT_EQUAL(r, 0);
361
362 r = amdgpu_bo_cpu_map(buf_handle, &msg);
363 CU_ASSERT_EQUAL(r, 0);
364
365 memcpy(msg, uvd_destroy_msg, sizeof(uvd_destroy_msg));
366 if (family_id >= AMDGPU_FAMILY_VI)
367 ((uint8_t*)msg)[0x10] = 7;
368
369 r = amdgpu_bo_cpu_unmap(buf_handle);
370 CU_ASSERT_EQUAL(r, 0);
371
372 num_resources = 0;
373 resources[num_resources++] = buf_handle;
374 resources[num_resources++] = ib_handle;
375
376 i = 0;
377 uvd_cmd(va, 0x0, &i);
378 for (; i % 16; ++i)
379 ib_cpu[i] = 0x80000000;
380
381 r = submit(i, AMDGPU_HW_IP_UVD);
382 CU_ASSERT_EQUAL(r, 0);
383
384 r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0, AMDGPU_VA_OP_UNMAP);
385 CU_ASSERT_EQUAL(r, 0);
386
387 r = amdgpu_va_range_free(va_handle);
388 CU_ASSERT_EQUAL(r, 0);
389
390 r = amdgpu_bo_free(buf_handle);
391 CU_ASSERT_EQUAL(r, 0);
392}
diff --git a/tests/amdgpu/frame.h b/tests/amdgpu/frame.h
new file mode 100644
index 00000000..4c946c27
--- /dev/null
+++ b/tests/amdgpu/frame.h
@@ -0,0 +1,1949 @@
1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifndef _frame_h_
25#define _frame_h_
26
27const uint8_t frame[] = {
28 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
29 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
30 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
31 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
32 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
33 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
34 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
35 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
36 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
37 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
38 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
39 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
40 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
41 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
42 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
43 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
44 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
45 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
46 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
47 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
48 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
49 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
50 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
51 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
52 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
53 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
54 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
55 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
56 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
57 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
58 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
59 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
60 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
61 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
62 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
63 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
64 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
65 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
66 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
67 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
68 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
69 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
70 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
71 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
72 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
73 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
74 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
75 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
76 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
77 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
78 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
79 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
80 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
81 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
82 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
83 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
84 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
85 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
86 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
87 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
88 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
89 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
90 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
91 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
92 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
93 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
94 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
95 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
96 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
97 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
98 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
99 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
100 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
101 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
102 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
103 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
104 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
105 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
106 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
107 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
108 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
109 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
110 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
111 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
112 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
113 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
114 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
115 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
116 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
117 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
118 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
119 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
120 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
121 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
122 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
123 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
124 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
125 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
126 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
127 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
128 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
129 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
130 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
131 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
132 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
133 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
134 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
135 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
136 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
137 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
138 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
139 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
140 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
141 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
142 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
143 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
144 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
145 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
146 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
147 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
148 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
149 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
150 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
151 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
152 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
153 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
154 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
155 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
156 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
157 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
158 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
159 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
160 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
161 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
162 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
163 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
164 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
165 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
166 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
167 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
168 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
169 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
170 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
171 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
172 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
173 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
174 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
175 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
176 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
177 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
178 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
179 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
180 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
181 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
182 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
183 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
184 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
185 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
186 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
187 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
188 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
189 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
190 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
191 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
192 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
193 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
194 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
195 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
196 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
197 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
198 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
199 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
200 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
201 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
202 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
203 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
204 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
205 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
206 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
207 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
208 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
209 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
210 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
211 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
212 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
213 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
214 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
215 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
216 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
217 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
218 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
219 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
220 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
221 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
222 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
223 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
224 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
225 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
226 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
227 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
228 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
229 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
230 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
231 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
232 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
233 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
234 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
235 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
236 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
237 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
238 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
239 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
240 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
241 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
242 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
243 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
244 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
245 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
246 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
247 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
248 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
249 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
250 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
251 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
252 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
253 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
254 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
255 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
256 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
257 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
258 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
259 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
260 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
261 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
262 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
263 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
264 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
265 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
266 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
267 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
268 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
269 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
270 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
271 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
272 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
273 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
274 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
275 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
276 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
277 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
278 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
279 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
280 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
281 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
282 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
283 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
284 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
285 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
286 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
287 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
288 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
289 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
290 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
291 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
292 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
293 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
294 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
295 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
296 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
297 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
298 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
299 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
300 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
301 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
302 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
303 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
304 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
305 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
306 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
307 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
308 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
309 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
310 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
311 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
312 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
313 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
314 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
315 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
316 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
317 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
318 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
319 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
320 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
321 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
322 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
323 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
324 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
325 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
326 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
327 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
328 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
329 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
330 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
331 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
332 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
333 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
334 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
335 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
336 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
337 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
338 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
339 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
340 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
341 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
342 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
343 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
344 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
345 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
346 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
347 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
348 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
349 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
350 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
351 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
352 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
353 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
354 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
355 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
356 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
357 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
358 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
359 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
360 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
361 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
362 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
363 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
364 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
365 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
366 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
367 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
368 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
369 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
370 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
371 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
372 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
373 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
374 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
375 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
376 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
377 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
378 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
379 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
380 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
381 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
382 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
383 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
384 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
385 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
386 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
387 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
388 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
389 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
390 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
391 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
392 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
393 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
394 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
395 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
396 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
397 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
398 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
399 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
400 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
401 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
402 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
403 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
404 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
405 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
406 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
407 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
408 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
409 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
410 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
411 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
412 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
413 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
414 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
415 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
416 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
417 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
418 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
419 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
420 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
421 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
422 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
423 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
424 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
425 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
426 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
427 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
428 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
429 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
430 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
431 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
432 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
433 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
434 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
435 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
436 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
437 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
438 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
439 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
440 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
441 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
442 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
443 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
444 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
445 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
446 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
447 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
448 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
449 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
450 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
451 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
452 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
453 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
454 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
455 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
456 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
457 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
458 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
459 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
460 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
461 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
462 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
463 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
464 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
465 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
466 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
467 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
468 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
469 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
470 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
471 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
472 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
473 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
474 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
475 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
476 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
477 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
478 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
479 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
480 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
481 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
482 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
483 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
484 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
485 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
486 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
487 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
488 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
489 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
490 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
491 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
492 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
493 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
494 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
495 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
496 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
497 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
498 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
499 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
500 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
501 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
502 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
503 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
504 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
505 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
506 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
507 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
508 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
509 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
510 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
511 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
512 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
513 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
514 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
515 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
516 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
517 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
518 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
519 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
520 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
521 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
522 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
523 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
524 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
525 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
526 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
527 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
528 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
529 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
530 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
531 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
532 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
533 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
534 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
535 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
536 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
537 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
538 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
539 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
540 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
541 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
542 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
543 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
544 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
545 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
546 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
547 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
548 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
549 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
550 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
551 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
552 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
553 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
554 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
555 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
556 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
557 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
558 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
559 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
560 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
561 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
562 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
563 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
564 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
565 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
566 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
567 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
568 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
569 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
570 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
571 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
572 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
573 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
574 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
575 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
576 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
577 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
578 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
579 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
580 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
581 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
582 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
583 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
584 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
585 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
586 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
587 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
588 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
589 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
590 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
591 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
592 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
593 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
594 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
595 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
596 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
597 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
598 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
599 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
600 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
601 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
602 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
603 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
604 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
605 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
606 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
607 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
608 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
609 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
610 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
611 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
612 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
613 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
614 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
615 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
616 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
617 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
618 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
619 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
620 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
621 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
622 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
623 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
624 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
625 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
626 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
627 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
628 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
629 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
630 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
631 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
632 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
633 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
634 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
635 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
636 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
637 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
638 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
639 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
640 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
641 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
642 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
643 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
644 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
645 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
646 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
647 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
648 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
649 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
650 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
651 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
652 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
653 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
654 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
655 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
656 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
657 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
658 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
659 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
660 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
661 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
662 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
663 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
664 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
665 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
666 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
667 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
668 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
669 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
670 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
671 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
672 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
673 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
674 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
675 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
676 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
677 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
678 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
679 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
680 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
681 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
682 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
683 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
684 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
685 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
686 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
687 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
688 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
689 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
690 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
691 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
692 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
693 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
694 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
695 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
696 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
697 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
698 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
699 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
700 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
701 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
702 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
703 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
704 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
705 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
706 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
707 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
708 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
709 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
710 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
711 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
712 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
713 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
714 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
715 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
716 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
717 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
718 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
719 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
720 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
721 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
722 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
723 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
724 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
725 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
726 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
727 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
728 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
729 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
730 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
731 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
732 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
733 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
734 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
735 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
736 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
737 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
738 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
739 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
740 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
741 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
742 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
743 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
744 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
745 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
746 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
747 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
748 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
749 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
750 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
751 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
752 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
753 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
754 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
755 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
756 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
757 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
758 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
759 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
760 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
761 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
762 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
763 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
764 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
765 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
766 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
767 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
768 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
769 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
770 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
771 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
772 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
773 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
774 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
775 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
776 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
777 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
778 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
779 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
780 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
781 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
782 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
783 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
784 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
785 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
786 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
787 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
788 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
789 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
790 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
791 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
792 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
793 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
794 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
795 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
796 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
797 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
798 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
799 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
800 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
801 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
802 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
803 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
804 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
805 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
806 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
807 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
808 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
809 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
810 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
811 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
812 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
813 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
814 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
815 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
816 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
817 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
818 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
819 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
820 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
821 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
822 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
823 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
824 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
825 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
826 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
827 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
828 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
829 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
830 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
831 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
832 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
833 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
834 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
835 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
836 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
837 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
838 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
839 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
840 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
841 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
842 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
843 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
844 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
845 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
846 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
847 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
848 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
849 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
850 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
851 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
852 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
853 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
854 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
855 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
856 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
857 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
858 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
859 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
860 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
861 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
862 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
863 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
864 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
865 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
866 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
867 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
868 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
869 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
870 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa,
871 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
872 0xaa, 0xaa, 0xaa, 0xaa, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
873 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
874 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
875 0x6a, 0x6a, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
876 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
877 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
878 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
879 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
880 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
881 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
882 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
883 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
884 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
885 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
886 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
887 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
888 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
889 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
890 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
891 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
892 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
893 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
894 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
895 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
896 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
897 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
898 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
899 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
900 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
901 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
902 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
903 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
904 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
905 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
906 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
907 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
908 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
909 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
910 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
911 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
912 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
913 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
914 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
915 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
916 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
917 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
918 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
919 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
920 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
921 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
922 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
923 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
924 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
925 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
926 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
927 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
928 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
929 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
930 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
931 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
932 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
933 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
934 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
935 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
936 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
937 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
938 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
939 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
940 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
941 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
942 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
943 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
944 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
945 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
946 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
947 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
948 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
949 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
950 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
951 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
952 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
953 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
954 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
955 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
956 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
957 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
958 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
959 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
960 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
961 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
962 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
963 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
964 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
965 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
966 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
967 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
968 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
969 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
970 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
971 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
972 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
973 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
974 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
975 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
976 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
977 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
978 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
979 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
980 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6a, 0x6a, 0x6a,
981 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
982 0x6a, 0x6a, 0x6a, 0x6a, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
983 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
984 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
985 0xaa, 0xaa, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
986 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
987 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
988 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
989 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
990 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
991 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
992 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
994 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
995 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0xcd, 0x13, 0x67, 0xa2, 0x2b, 0xa5, 0x29,
996 0x5d, 0xcb, 0xd5, 0xa4, 0x27, 0x2a, 0x62, 0x20, 0x70, 0x78, 0x6d, 0xe9, 0x1e, 0xeb, 0x25, 0xa6,
997 0x62, 0x29, 0x13, 0xa4, 0xab, 0x29, 0x12, 0x35, 0x4c, 0x77, 0x73, 0x42, 0xe0, 0xd0, 0x62, 0xa5,
998 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
999 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1000 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1001 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1002 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1003 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1004 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1005 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xad, 0x17, 0x5c, 0xc3, 0xdc, 0x41, 0x1e, 0xbe,
1006 0x4e, 0x90, 0xab, 0xbf, 0x86, 0x33, 0x1f, 0xeb, 0x15, 0xac, 0x64, 0x38, 0xd0, 0x44, 0xe6, 0x3e,
1007 0xe9, 0x50, 0x8f, 0x32, 0xbd, 0x18, 0x7a, 0x4a, 0xaa, 0x12, 0x61, 0x91, 0x62, 0xaa, 0xd9, 0x6e,
1008 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1009 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1010 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1011 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1012 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1013 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1014 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1015 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa4, 0xc6, 0x37, 0x7f, 0x6e, 0x6a, 0xa6, 0xd0,
1016 0xd6, 0x84, 0x51, 0x96, 0x13, 0xd6, 0xc4, 0x3e, 0x60, 0x36, 0x62, 0xbd, 0xd9, 0xe2, 0x78, 0xe3,
1017 0x83, 0x99, 0xda, 0x8e, 0x31, 0xd4, 0x64, 0x1f, 0xc7, 0x1b, 0xbe, 0xaa, 0x76, 0x22, 0x6b, 0x6b,
1018 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1019 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1020 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1021 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1022 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1023 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1024 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1025 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x69, 0xb0, 0x8a, 0xcc, 0x74, 0x17, 0x4c,
1026 0x98, 0xe1, 0xc1, 0xaa, 0x19, 0xe5, 0xc3, 0xce, 0x69, 0xb1, 0xe5, 0x62, 0xe7, 0x2f, 0xe0, 0xc4,
1027 0xe8, 0x25, 0x84, 0xe8, 0x5f, 0x84, 0xb0, 0xab, 0x40, 0x3b, 0x9e, 0x95, 0x27, 0x44, 0x1e, 0x7a,
1028 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1029 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1030 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1031 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1032 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1033 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1034 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1035 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe4, 0x77, 0xc8, 0x7d, 0xd2, 0x6e, 0xe5, 0x1f,
1036 0x8d, 0x33, 0x7c, 0x8e, 0x90, 0xbe, 0x1f, 0xb9, 0x5b, 0xc1, 0x5d, 0xdf, 0xc6, 0x23, 0x25, 0xc9,
1037 0x25, 0xb1, 0x13, 0x5e, 0x7c, 0x93, 0x67, 0xdf, 0x9b, 0x8f, 0x71, 0xb8, 0x34, 0xa4, 0x6b, 0xa1,
1038 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1039 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1040 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1041 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1042 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1043 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1044 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1045 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0xb8, 0x74, 0xbb, 0xa5, 0x3b, 0x40, 0x12,
1046 0x2b, 0x14, 0x43, 0x36, 0x93, 0x26, 0xe8, 0xda, 0x22, 0xcf, 0xc2, 0x69, 0xb0, 0xd0, 0x7a, 0xb1,
1047 0xc8, 0x2a, 0x92, 0x27, 0x94, 0x19, 0x97, 0xb3, 0x92, 0x65, 0xc5, 0x8d, 0xe8, 0xa6, 0xd0, 0x9b,
1048 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1049 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1050 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1051 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1052 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1053 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1054 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1055 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x88, 0x92, 0x2e, 0x4b, 0x64, 0xda, 0xce, 0x16,
1056 0x67, 0x70, 0xeb, 0x5c, 0x86, 0x6b, 0xc2, 0xe4, 0xbd, 0xdc, 0x46, 0x28, 0xd8, 0xd4, 0x19, 0x69,
1057 0xd5, 0xcf, 0x8e, 0x89, 0x40, 0x96, 0x7b, 0xb2, 0xc9, 0x5e, 0x18, 0xc6, 0xd6, 0xd2, 0x3c, 0x4a,
1058 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1059 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1060 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1061 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1062 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1064 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1065 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x50, 0x88, 0xb8, 0x9a, 0x8c, 0xc8, 0xae,
1066 0xae, 0xcd, 0x63, 0x62, 0xc3, 0x8a, 0x32, 0xb3, 0x5c, 0x1c, 0xa2, 0x55, 0x27, 0x55, 0x87, 0x6b,
1067 0x3e, 0x33, 0xd6, 0x70, 0xd0, 0x59, 0x76, 0xb0, 0xcd, 0x4a, 0x6e, 0x4a, 0xb1, 0xa1, 0x17, 0x24,
1068 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1069 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1070 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1071 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1072 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1073 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1074 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1075 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xc8, 0xb5, 0xe3, 0x7a, 0x17, 0x63, 0x70, 0xca,
1076 0x37, 0xbd, 0x1f, 0x72, 0x5e, 0x2f, 0x7c, 0xb7, 0xd2, 0xcb, 0xa8, 0xa9, 0x13, 0x98, 0x2b, 0x7e,
1077 0x74, 0x3f, 0x94, 0x6f, 0x8c, 0x1a, 0xce, 0x38, 0x61, 0x72, 0xe2, 0x18, 0x4e, 0xac, 0x5c, 0xc3,
1078 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1079 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1080 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1081 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1082 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1083 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1084 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1085 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x92, 0xd8, 0xb7, 0x88, 0xa8, 0x6e, 0xc5, 0xce,
1086 0x1f, 0x4a, 0x64, 0x3b, 0x1a, 0x21, 0x9f, 0xa6, 0x46, 0xe7, 0x1a, 0xcf, 0xc8, 0x20, 0xc1, 0x20,
1087 0x83, 0xbe, 0x5b, 0x99, 0x4d, 0xd4, 0x5e, 0xb3, 0xc3, 0x4b, 0xab, 0x3e, 0xc7, 0x85, 0xea, 0xc4,
1088 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1089 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1090 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1091 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1092 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1093 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1094 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1095 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x48, 0xe0, 0x84, 0xa8, 0x1d, 0x81, 0x62,
1096 0x74, 0x67, 0xb0, 0x32, 0x4c, 0x23, 0x56, 0xd0, 0x85, 0x9b, 0x20, 0xca, 0xb4, 0x49, 0xdd, 0xad,
1097 0x1f, 0xab, 0xcf, 0x16, 0x7d, 0xbd, 0x78, 0xb0, 0xd3, 0xa0, 0x5c, 0x50, 0xa1, 0xd7, 0x37, 0xa0,
1098 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1099 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1100 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1101 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1102 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1104 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1105 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x55, 0x97, 0xd6, 0x93, 0x6c, 0xd2, 0xa1,
1106 0x94, 0xc2, 0x2c, 0x51, 0x68, 0x34, 0x88, 0xc7, 0x8c, 0x1f, 0x3f, 0x93, 0x68, 0x86, 0xb1, 0xa5,
1107 0xe1, 0x56, 0x89, 0x20, 0xa5, 0xe2, 0x28, 0x9a, 0x11, 0x8f, 0xa4, 0xa7, 0x81, 0x6d, 0xe2, 0x87,
1108 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1109 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1110 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1111 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1112 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1114 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1115 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe2, 0x34, 0x79, 0x8d, 0xe2, 0xe1, 0xa3, 0x38,
1116 0x83, 0x3b, 0xb0, 0x7f, 0x4b, 0x2b, 0x44, 0xb7, 0x68, 0x21, 0x85, 0x79, 0x74, 0x8c, 0xbc, 0x65,
1117 0xbb, 0x16, 0xd0, 0x2a, 0xb7, 0x70, 0x13, 0x94, 0xc3, 0x87, 0x23, 0x46, 0x2f, 0xe3, 0xb7, 0xcf,
1118 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1119 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1120 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1121 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1122 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1124 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1125 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0xdd, 0x60, 0x5d, 0xc3, 0xd6, 0x75, 0x20,
1126 0x78, 0xbd, 0x49, 0x23, 0xaf, 0x1e, 0xa2, 0x14, 0xca, 0x81, 0x39, 0xbb, 0x19, 0xc2, 0x82, 0xde,
1127 0x68, 0xbe, 0xdb, 0xdd, 0xa4, 0x86, 0x51, 0xe7, 0xad, 0x2b, 0x25, 0xb0, 0xb7, 0x3d, 0xd0, 0xac,
1128 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1129 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1130 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1131 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1132 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1134 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1135 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x50, 0xa9, 0x7e, 0x3b, 0xc0, 0x41, 0x9a,
1136 0x6e, 0xd0, 0x8f, 0x4a, 0x21, 0xd1, 0xe1, 0x9f, 0xdb, 0xb6, 0xe2, 0x41, 0x4a, 0x15, 0xb5, 0x95,
1137 0x64, 0x97, 0xd3, 0x42, 0xc5, 0x63, 0xdd, 0xb7, 0x57, 0x6c, 0xc3, 0x54, 0x91, 0x2b, 0xdc, 0x52,
1138 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1139 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1140 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1141 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1142 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1144 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1145 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xb2, 0xe1, 0x14, 0x37, 0x92, 0xea, 0xb8, 0xc3,
1146 0x95, 0x4b, 0x31, 0xab, 0x9b, 0xb8, 0x8f, 0xca, 0x66, 0x45, 0xae, 0x71, 0xaf, 0xb8, 0x2b, 0x57,
1147 0x87, 0x17, 0x90, 0x28, 0x98, 0x62, 0x47, 0x2c, 0xeb, 0x92, 0x79, 0x26, 0x52, 0x7d, 0x70, 0x88,
1148 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1149 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1150 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1151 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1152 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1154 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1155 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa3, 0x38, 0x7a, 0xe7, 0x7e, 0x27, 0x49, 0xbd,
1156 0xe2, 0xcc, 0x88, 0xe6, 0x36, 0xae, 0xd6, 0x7c, 0x48, 0xe3, 0xe6, 0x7d, 0x11, 0xd4, 0xa0, 0x3e,
1157 0x6e, 0x9d, 0xdb, 0x9b, 0xdc, 0xb0, 0x70, 0xdc, 0x58, 0x5b, 0xda, 0x99, 0x92, 0x65, 0x48, 0x86,
1158 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1159 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1160 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1161 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1162 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1164 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1165 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x52, 0x5c, 0x69, 0xd6, 0x8d, 0xb1, 0x5f,
1166 0xa3, 0x1c, 0xe1, 0x1e, 0x78, 0x15, 0x97, 0x9e, 0x44, 0xdf, 0x56, 0x60, 0x38, 0x18, 0x43, 0x1b,
1167 0xc1, 0x91, 0x6e, 0x48, 0x98, 0xe2, 0x19, 0x36, 0x9d, 0x6c, 0x23, 0x5a, 0x97, 0xa4, 0x26, 0x13,
1168 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1169 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1170 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1171 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1172 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1174 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1175 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x12, 0x33, 0x7a, 0x68, 0xb2, 0x29, 0x92, 0x81,
1176 0xa0, 0x5a, 0x9e, 0xd5, 0xbd, 0xb7, 0x4f, 0x13, 0x55, 0xb7, 0xe7, 0x73, 0x52, 0x32, 0x21, 0xbf,
1177 0x3a, 0x1b, 0xb1, 0x60, 0x19, 0x5f, 0x77, 0x8b, 0x7c, 0x2a, 0x87, 0x26, 0x82, 0x7f, 0x1d, 0xda,
1178 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1179 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1180 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1181 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1182 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1184 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1185 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xd6, 0xa3, 0xcd, 0xc3, 0x76, 0x48, 0x21, 0xd8,
1186 0x21, 0xab, 0x86, 0xc2, 0x5f, 0x57, 0xca, 0x7f, 0x38, 0x19, 0x4a, 0x20, 0xd6, 0xe8, 0x51, 0x22,
1187 0x5b, 0xb9, 0x24, 0xb8, 0x85, 0x87, 0x7b, 0xe1, 0x38, 0xbc, 0xdd, 0xad, 0xdd, 0xca, 0x1f, 0xc7,
1188 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1189 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1190 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1191 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1192 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1194 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1195 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x4c, 0x1f, 0xdb, 0x80, 0xc3, 0xc0, 0x64,
1196 0xc3, 0x44, 0x9a, 0x1e, 0xd7, 0xd3, 0x1f, 0xa5, 0xba, 0xe3, 0x26, 0xe8, 0x7e, 0x8d, 0x5c, 0xaa,
1197 0xb1, 0x82, 0xc9, 0x3a, 0xd7, 0xd5, 0xb0, 0xd0, 0x45, 0x53, 0x8a, 0x65, 0x78, 0xe4, 0x6c, 0x86,
1198 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1199 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1200 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1201 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1202 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1204 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1205 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x7a, 0xc3, 0xdc, 0xbb, 0x6b, 0x44, 0x70,
1206 0x10, 0x86, 0x88, 0x5c, 0x2e, 0xdc, 0x25, 0x4b, 0xb7, 0xb1, 0x88, 0xca, 0x27, 0xb1, 0x83, 0x2c,
1207 0x21, 0x9c, 0xe2, 0xbf, 0xe4, 0x2a, 0x35, 0x19, 0xdc, 0x99, 0xbc, 0x4a, 0x44, 0xd6, 0x4d, 0x75,
1208 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1209 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1210 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1211 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1212 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1214 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1215 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x5b, 0x67, 0x73, 0x35, 0xe3, 0x3e, 0xb4,
1216 0x7a, 0x48, 0x13, 0x49, 0x47, 0xac, 0xdc, 0xa8, 0x1a, 0x2b, 0x44, 0xb4, 0xac, 0x99, 0x82, 0x13,
1217 0xc8, 0x7b, 0x7e, 0x9f, 0xeb, 0xab, 0xa2, 0xc8, 0xb2, 0x3e, 0x96, 0xd3, 0x53, 0x13, 0x33, 0x42,
1218 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1219 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1220 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1221 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1222 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1224 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1225 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2c, 0xdd, 0x42, 0x16, 0x1e, 0x35, 0x6a, 0xa0,
1226 0x5f, 0x93, 0x62, 0xc5, 0x6d, 0xc3, 0xde, 0x84, 0x4b, 0xdf, 0xde, 0xab, 0xbc, 0x31, 0xcd, 0xa1,
1227 0xa6, 0x10, 0x33, 0x48, 0x4c, 0x6f, 0x6a, 0xc0, 0xd8, 0x97, 0x2e, 0xb5, 0x48, 0x74, 0x70, 0x29,
1228 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1229 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1230 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1231 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1232 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1234 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1235 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0xd8, 0x5a, 0x9a, 0xc4, 0x1a, 0xd4, 0xa7,
1236 0x73, 0xc3, 0x1f, 0x10, 0x54, 0x95, 0x59, 0x16, 0x53, 0x88, 0x14, 0x30, 0xbd, 0x8c, 0x6f, 0x8d,
1237 0x19, 0x2f, 0xaf, 0x14, 0x88, 0xd6, 0x79, 0x33, 0xd6, 0xd6, 0x22, 0xb6, 0x9a, 0xa0, 0xcb, 0x90,
1238 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1239 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1240 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1241 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1242 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1244 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1245 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x93, 0xe1, 0xcc, 0x2f, 0x51, 0x67, 0x8a, 0x17,
1246 0xc3, 0xaa, 0x31, 0x31, 0x8c, 0xb3, 0xaa, 0x98, 0xb6, 0x5d, 0xe2, 0x6e, 0xa1, 0xcf, 0x10, 0xd4,
1247 0x8e, 0x6c, 0x93, 0xbd, 0x8b, 0xe9, 0x4f, 0x55, 0xdc, 0x3c, 0x4a, 0xad, 0x76, 0xcf, 0xea, 0xb7,
1248 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1249 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1250 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1251 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1252 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1254 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1255 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x50, 0x85, 0xcf, 0x57, 0x56, 0xa3, 0x1a,
1256 0x49, 0x25, 0xbe, 0x8d, 0x54, 0xa7, 0x78, 0x68, 0x76, 0x53, 0xc7, 0x59, 0x59, 0x66, 0xa1, 0xe4,
1257 0xa0, 0x68, 0x4d, 0x57, 0x85, 0x62, 0x2a, 0x56, 0x68, 0x38, 0x2b, 0xd3, 0xbd, 0x9a, 0xc4, 0xe0,
1258 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1259 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1260 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1261 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1262 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1264 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1265 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xb9, 0x40, 0x3e, 0x19, 0x40, 0xab, 0x60, 0xba,
1266 0xbf, 0x68, 0xb8, 0xe7, 0xa3, 0x3c, 0x73, 0x9b, 0x12, 0x68, 0xca, 0x89, 0x3f, 0x45, 0x67, 0xbd,
1267 0xd9, 0x3c, 0xd4, 0xc0, 0xa5, 0x15, 0x98, 0x6a, 0x81, 0x8b, 0x38, 0x6e, 0x27, 0x4c, 0x30, 0x29,
1268 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1269 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1270 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1271 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1272 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1274 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1275 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xbd, 0x8a, 0x61, 0x55, 0x4f, 0xb8, 0x2b, 0x6b,
1276 0x3b, 0x19, 0xe2, 0x10, 0x44, 0xc7, 0x51, 0x4a, 0x3a, 0x3b, 0xc3, 0x3e, 0xab, 0xca, 0x84, 0x86,
1277 0xab, 0xe4, 0xa3, 0x5a, 0xa7, 0xaf, 0x4e, 0x80, 0xa0, 0x95, 0x94, 0xde, 0xd6, 0x6e, 0x2f, 0x68,
1278 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1279 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1280 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1281 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1282 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1284 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1285 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x36, 0x8c, 0x49, 0x53, 0x7a, 0x50, 0xcb,
1286 0x75, 0x13, 0xcb, 0xab, 0x92, 0x70, 0x14, 0x6a, 0x8d, 0x4c, 0x9c, 0x5c, 0xa5, 0x69, 0x46, 0x1d,
1287 0x99, 0x68, 0x71, 0x72, 0x44, 0x87, 0xe7, 0xa8, 0xe6, 0x99, 0x9d, 0xdb, 0x31, 0x86, 0xc9, 0x9c,
1288 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1289 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1290 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1291 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1292 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1294 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1295 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xdd, 0x7d, 0xe8, 0xd0, 0x1c, 0x30, 0x8d, 0x2d,
1296 0x56, 0x5a, 0x1f, 0x1d, 0xc2, 0xa2, 0x7f, 0xcb, 0xd8, 0xbc, 0xcb, 0x6e, 0x12, 0x6e, 0x26, 0x62,
1297 0xeb, 0x48, 0x32, 0x91, 0x7b, 0x59, 0x6d, 0xac, 0xc7, 0x7a, 0x34, 0x55, 0xc3, 0x54, 0x9c, 0xbf,
1298 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1299 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1300 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
1301 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1302 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
1303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
1304 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1305 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0xea, 0xd9, 0x1f, 0xbd, 0xc9, 0x84, 0xe8,
1306 0xb1, 0x92, 0xc0, 0x7a, 0xde, 0x74, 0xe8, 0x87, 0xb1, 0xd6, 0x22, 0xc9, 0x19, 0x41, 0x7e, 0x36,
1307 0x62, 0xc6, 0x62, 0x99, 0x93, 0x4d, 0xa9, 0x7c, 0x5c, 0x23, 0x32, 0xe5, 0x5a, 0x4d, 0xbc, 0x87,
1308 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1309 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1310 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1311 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1312 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1313 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1314 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1315 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1316 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1317 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1318 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1319 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1320 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1321 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1322 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1323 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1324 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1325 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1326 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1327 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1328 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1329 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1330 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1331 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1332 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1333 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1334 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1335 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1336 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1337 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1338 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1339 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1340 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1341 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1342 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1343 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1344 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1345 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1346 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1347 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1348 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1349 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1350 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1351 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1352 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1353 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1354 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1355 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1356 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1357 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1358 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1359 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1360 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1361 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1362 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1363 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1364 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1365 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1366 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1367 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1368 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1369 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1370 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1371 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1372 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1373 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1374 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1375 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1376 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1377 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1378 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1379 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1380 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1381 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1382 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1383 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1384 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1385 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1386 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1387 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1388 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1389 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1390 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1391 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1392 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1393 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1394 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1395 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1396 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1397 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1398 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1399 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1400 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1401 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1402 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1403 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1404 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1405 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1406 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1407 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1408 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1409 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1410 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1411 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1412 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1413 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1414 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1415 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1416 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1417 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1418 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1419 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1420 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1421 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1422 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1423 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1424 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1425 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1426 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1427 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1428 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1429 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1430 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1431 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1432 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1433 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1434 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1435 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1436 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1437 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1438 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1439 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1440 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1441 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1442 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1443 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1444 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1445 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1446 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1447 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1448 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1449 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1450 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1451 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1452 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1453 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1454 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1455 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1456 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1457 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1458 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1459 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1460 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1461 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1462 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1463 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1464 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1465 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1466 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1467 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1468 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1469 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1470 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1471 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1472 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1473 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1474 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1475 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1476 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1477 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1478 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1479 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1480 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1481 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1482 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1483 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1484 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1485 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1486 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1487 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1488 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1489 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1490 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1491 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1492 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1493 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1494 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1495 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1496 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1497 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1498 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1499 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1500 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1501 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1502 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1503 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1504 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1505 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1506 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1507 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1508 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1509 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1510 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1511 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1512 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1513 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1514 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1515 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1516 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1517 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1518 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1519 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1520 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1521 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1522 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1523 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1524 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1525 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1526 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1527 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1528 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1529 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1530 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1531 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1532 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1533 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1534 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1535 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1536 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1537 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1538 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1539 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1540 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1541 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1542 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1543 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1544 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1545 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1546 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1547 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1548 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1549 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1550 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1551 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1552 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1553 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1554 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1555 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1556 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1557 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1558 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1559 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1560 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1561 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1562 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1563 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1564 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1565 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1566 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1567 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1568 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1569 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1570 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1571 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1572 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1573 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1574 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1575 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1576 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1577 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1578 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1579 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1580 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1581 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1582 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1583 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1584 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1585 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1586 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1587 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1588 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1589 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1590 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1591 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1592 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1593 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1594 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1595 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1596 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1597 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1598 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1599 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1600 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1601 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1602 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1603 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1604 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1605 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1606 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1607 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1608 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1609 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1610 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1611 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1612 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1613 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1614 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1615 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1616 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1617 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1618 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1619 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1620 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1621 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1622 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1623 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1624 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1625 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1626 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1627 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1628 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1629 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1630 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1631 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1632 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1633 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1634 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1635 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1636 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1637 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1638 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1639 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1640 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1641 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1642 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1643 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1644 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1645 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1646 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1647 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1648 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1649 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1650 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1651 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1652 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1653 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1654 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1655 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1656 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1657 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1658 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1659 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1660 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1661 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1662 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1663 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1664 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1665 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1666 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1667 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1668 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1669 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1670 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1671 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1672 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1673 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1674 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1675 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1676 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1677 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1678 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1679 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1680 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1681 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1682 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1683 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1684 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1685 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1686 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1687 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1688 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1689 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1690 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1691 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1692 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1693 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1694 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1695 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1696 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1697 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1698 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1699 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1700 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1701 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1702 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1703 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1704 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1705 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1706 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1707 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1708 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1709 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1710 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1711 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1712 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1713 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1714 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1715 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1716 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1717 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1718 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1719 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92,
1720 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x10, 0x92, 0x5b, 0x51, 0xa6, 0x10,
1721 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1722 0xa6, 0x10, 0xa6, 0x10, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22,
1723 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x36, 0x22, 0x80, 0x80, 0xca, 0xde, 0xca, 0xde,
1724 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1725 0xca, 0xde, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0,
1726 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0x5a, 0xf0, 0xa5, 0xaf, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1727 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1728 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1729 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1730 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
1731 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1732 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1733 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
1734 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1735 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1736 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1737 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1738 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1739 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1740 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
1741 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1742 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1743 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
1744 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1745 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1746 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1747 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1748 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1749 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1750 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
1751 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1752 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1753 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
1754 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1755 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1756 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1757 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1758 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1759 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1760 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
1761 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1762 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1763 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
1764 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1765 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1766 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1767 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1768 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1769 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1770 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
1771 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1772 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1773 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
1774 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1775 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1776 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1777 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1778 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e,
1779 0xf0, 0x6e, 0xf0, 0x6e, 0xf0, 0x6e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1780 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa5, 0xaf, 0xca, 0xde,
1781 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde, 0xca, 0xde,
1782 0xca, 0xde, 0xca, 0xde, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1783 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x93, 0x48, 0xa6, 0x10, 0xa6, 0x10,
1784 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10, 0xa6, 0x10,
1785 0xa6, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1786 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1787 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1788 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1789 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1790 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1791 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1792 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1793 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1794 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1795 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1796 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1797 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1798 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1799 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1800 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1801 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1802 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1803 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1804 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1805 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1806 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1807 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1808 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1809 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1810 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1811 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1812 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1813 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1814 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1815 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1816 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1817 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1818 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1819 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1820 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1821 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1822 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1823 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1824 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1825 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1826 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1827 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1828 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1829 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1830 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1831 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1832 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1833 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1834 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1835 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1836 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1837 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1838 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1839 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1840 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1841 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1842 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1843 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1844 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1845 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1846 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1847 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1848 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1849 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1850 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1851 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1852 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1853 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1854 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1855 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1856 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1857 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1858 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1859 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1860 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1861 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1862 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1863 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1864 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1865 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1866 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1867 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1868 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1869 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1870 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1871 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1872 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1873 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1874 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1875 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1876 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1877 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1878 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1879 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1880 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1881 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1882 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1883 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1884 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1885 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1886 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1887 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1888 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1889 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1890 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1891 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1892 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1893 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1894 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1895 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1896 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1897 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1898 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1899 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1900 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1901 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1902 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1903 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1904 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1905 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1906 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1907 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1908 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1909 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1910 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1911 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1912 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1913 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1914 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1915 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1916 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1917 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1918 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1919 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1920 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1921 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1922 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1923 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1924 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1925 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1926 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1927 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1928 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1929 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1930 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1931 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1932 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1933 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1934 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1935 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1936 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1937 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1938 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15,
1939 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0xc6, 0x15, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1940 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1941 0x80, 0x80, 0x80, 0x80, 0xb6, 0xa3, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1942 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6, 0xeb, 0xc6,
1943 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1944 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1945 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1946 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1947 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
1948};
1949#endif
diff --git a/tests/amdgpu/uvd_messages.h b/tests/amdgpu/uvd_messages.h
new file mode 100644
index 00000000..00235cbb
--- /dev/null
+++ b/tests/amdgpu/uvd_messages.h
@@ -0,0 +1,813 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#ifndef _UVD_MESSAGES_H_
25#define _UVD_MESSAGES_H_
26
27static const uint8_t uvd_create_msg[] = {
28 0xe4,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
29 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x03,0x00,0x00,
30 0xe0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xf9,0xf2,0x00,0x00,0x00,0x00,0x00,
31 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
33 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
34 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
35 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
36 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
37 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
38 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
39 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
40 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
41 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
43 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
44 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
45 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
46 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
47 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
48 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
49 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
50 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
51 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
52 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
53 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
54 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
55 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
56 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
57 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
58 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
59 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
60 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
61 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
63 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
64 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
65 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
66 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
67 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
68 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
69 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
70 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
71 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
72 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
73 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
74 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
75 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
76 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
77 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
78 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
79 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
80 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
81 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
82 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
83 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
84 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
85 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
86 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
87 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
88 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
89 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
90 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
91 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
92 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
93 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
94 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
95 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
96 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
97 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
98 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
99 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
100 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
101 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
102 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
103 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
104 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
105 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
106 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
107 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
108 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
109 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
113 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
114 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
115 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
116 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
119 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
120 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
121 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
123 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
124 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
125 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
126 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
129 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
137 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
138 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
139 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
140 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
141 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
142 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
143 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
144 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
145 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
146 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
147 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
148 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
149 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
150 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
151 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
152 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
153 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
154 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
155 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
156 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
157 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
158 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
159 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
160 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
161 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
162 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
163 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
164 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
165 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
166 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
167 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
171 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
172 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
173 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
174 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
175 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
176 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
177 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
178 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
179 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
180 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
181 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
182 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
183 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
184 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
185 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
186 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
187 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
188 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
189 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
190 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
191 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
192 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
193 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
194 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
195 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
196 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
197 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
198 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
199 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
200 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
201 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
202 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
203 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
204 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
205 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
206 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
207 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
208 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
209 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
210 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
211 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
212 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
213 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
214 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
215 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
216 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
217 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
218 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
219 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
220 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
221 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
222 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
223 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
224 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
225 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
226 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
227 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
228 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
229 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
230 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
231 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
232 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
233 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
234 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
235 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
236 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
237 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
238 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
239 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
240 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
241 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
242 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
243 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
244 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
245 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
246 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
247 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
248 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
249 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
250 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
251};
252
253static const uint8_t uvd_bitstream[] ={
254 0x00,0x00,0x01,0x25,0xb8,0x20,0x20,0x21,0x44,0xc5,0x00,0x01,0x57,0x9b,0xef,0xbe,
255 0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,
256 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,
257 0xbe,0xfb,0xef,0xbe,0xff,0x87,0xff,0xc2,0x58,0x0e,0x00,0x02,0x02,0xa0,0x00,0x20,
258 0x3a,0x00,0x0d,0x00,0x01,0x01,0xa4,0xcb,0x94,0x73,0xeb,0xae,0xba,0xeb,0xae,0xba,
259 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
260 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
261 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
262 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
263 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
264 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
265 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
266 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
267 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
268 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
269 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
270 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
271 0xeb,0xae,0xba,0xeb,0xaf,0x00,0x00,0x01,0x25,0x00,0xa2,0xb8,0x20,0x20,0x21,0x44,
272 0xc5,0x00,0x01,0x57,0x9b,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,
273 0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,
274 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xff,0x87,0xff,0xc2,0x58,
275 0x0e,0x00,0x02,0x02,0xa0,0x00,0x20,0x3a,0x00,0x0d,0x00,0x01,0x01,0xa4,0xcb,0x94,
276 0x73,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
277 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
278 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
279 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
280 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
281 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
282 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
283 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
284 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
285 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
286 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
287 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
288 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xaf,0x00,0x00,0x01,0x25,
289 0x00,0x51,0x2e,0x08,0x08,0x08,0x51,0x31,0x40,0x00,0x55,0xe6,0xfb,0xef,0xbe,0xfb,
290 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,
291 0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,
292 0xfb,0xef,0xbf,0xe1,0xff,0xf0,0x96,0x03,0x80,0x00,0x80,0xa8,0x00,0x08,0x0e,0x80,
293 0x03,0x40,0x00,0x40,0x69,0x32,0xe5,0x1c,0xfa,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
294 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
295 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
296 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
297 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
298 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
299 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
300 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
301 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
302 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
303 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
304 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
305 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
306 0xae,0xba,0xeb,0xc0,0x00,0x00,0x01,0x25,0x00,0x79,0xae,0x08,0x08,0x08,0x51,0x31,
307 0x40,0x00,0x55,0xe6,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,
308 0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,
309 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbf,0xe1,0xff,0xf0,0x96,0x03,
310 0x80,0x00,0x80,0xa8,0x00,0x08,0x0e,0x80,0x03,0x40,0x00,0x40,0x69,0x32,0xe5,0x1c,
311 0xfa,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
312 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
313 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
314 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
315 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
316 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
317 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
318 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
319 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
320 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
321 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
322 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
323 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xc0,0x00,0x00,0x01,0x25,
324 0x00,0x28,0x8b,0x82,0x02,0x02,0x14,0x4c,0x50,0x00,0x15,0x79,0xbe,0xfb,0xef,0xbe,
325 0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,
326 0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,0xbe,0xfb,0xef,
327 0xbe,0xfb,0xef,0xf8,0x7f,0xfc,0x25,0x80,0xe0,0x00,0x20,0x2a,0x00,0x02,0x03,0xa0,
328 0x00,0xd0,0x00,0x10,0x1a,0x4c,0xb9,0x47,0x3e,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
329 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
330 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
331 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
332 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
333 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
334 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
335 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
336 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
337 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
338 0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,
339 0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,
340 0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,0xeb,0xae,0xba,
341 0xeb,0xae,0xba,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
342};
343
344static const uint8_t uvd_decode_msg[] = {
345 0xe4,0x0d,0x00,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x44,0x40,0x01,0x00,0x00,0x00,
346 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,
347 0x00,0x00,0x00,0x00,0x80,0xf9,0xf2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
348 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
349 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
350 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
351 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
352 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
353 0x00,0x00,0x00,0x00,0x00,0xc0,0x03,0x00,0x00,0x80,0x07,0x00,0x00,0x60,0x09,0x00,
354 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
355 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
356 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
357 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
358 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
359 0x02,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x88,0x00,0x00,0x00,
360 0x01,0x00,0x00,0x01,0x00,0x03,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
361 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
362 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
363 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
364 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
365 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
366 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
367 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
368 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
369 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
370 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
371 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
372 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
373 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
374 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
375 0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
376 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
377 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
378 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
379 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
380 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
381 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
382 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
383 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
384 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
385 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
386 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
387 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
388 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
389 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
390 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
391 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
392 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
393 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
394 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
395 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
396 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
397 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
398 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
399 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
400 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
401 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
402 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
403 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
404 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
405 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
406 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
407 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
408 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
409 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
410 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
411 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
412 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
413 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
414 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
415 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
416 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
417 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
418 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
419 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
420 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
421 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
422 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
423 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
424 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
425 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
426 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
427 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
428 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
429 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
430 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
431 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
432 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
433 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
434 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
435 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
436 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
437 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
438 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
439 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
440 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
441 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
442 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
443 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
444 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
445 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
446 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
447 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
448 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
449 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
450 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
451 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
452 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
453 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
454 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
455 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
456 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
457 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
458 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
459 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
460 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
461 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
462 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
463 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
464 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
465 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
466 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
467 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
468 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
469 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
470 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
471 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
472 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
473 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
474 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
475 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
476 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
477 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
478 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
479 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
480 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
481 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
482 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
483 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
484 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
485 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
486 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
487 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
488 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
489 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
490 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
491 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
492 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
493 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
494 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
495 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
496 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
497 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
498 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
499 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
500 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
501 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
502 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
503 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
504 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
505 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
506 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
507 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
508 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
509 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
510 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
511 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
512 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
513 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
514 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
515 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
516 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
517 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
518 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
519 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
520 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
521 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
522 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
523 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
524 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
525 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
526 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
527 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
528 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
529 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
530 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
531 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
532 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
533 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
534 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
535 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
536 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
537 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
538 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
539 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
540 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
541 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
542 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
543 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
544 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
545 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
546 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
547 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
548 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
549 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
550 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
551 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
552 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
553 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
554 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
555 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
556 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
557 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
558 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
560 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
561 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
562 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
563 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
564 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
565 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
566 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
567 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
568};
569
570static const uint8_t uvd_destroy_msg[] = {
571 0xe4,0x0d,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
572 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
574 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
575 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
576 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
577 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
578 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
579 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
580 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
581 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
582 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
583 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
584 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
585 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
586 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
587 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
588 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
589 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
590 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
591 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
592 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
593 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
594 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
595 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
596 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
597 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
598 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
599 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
600 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
601 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
602 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
603 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
604 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
605 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
606 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
607 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
608 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
609 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
610 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
611 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
612 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
613 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
614 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
615 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
616 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
617 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
618 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
619 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
620 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
621 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
622 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
623 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
624 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
625 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
626 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
627 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
628 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
629 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
630 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
631 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
632 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
633 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
634 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
635 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
636 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
637 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
638 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
639 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
640 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
641 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
642 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
643 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
644 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
645 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
646 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
647 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
648 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
649 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
650 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
651 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
652 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
653 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
654 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
655 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
656 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
657 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
658 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
659 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
660 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
661 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
662 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
663 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
664 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
665 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
666 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
667 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
668 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
669 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
670 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
671 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
672 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
673 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
674 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
675 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
676 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
677 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
678 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
679 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
680 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
681 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
682 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
683 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
684 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
685 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
686 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
687 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
688 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
689 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
690 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
691 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
692 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
693 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
694 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
695 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
696 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
697 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
698 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
699 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
700 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
701 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
702 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
703 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
704 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
705 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
706 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
707 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
708 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
709 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
710 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
711 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
712 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
713 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
714 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
715 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
716 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
717 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
718 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
719 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
720 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
721 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
722 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
723 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
724 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
725 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
726 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
727 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
728 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
729 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
730 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
731 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
732 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
733 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
734 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
735 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
736 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
737 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
738 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
739 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
740 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
741 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
742 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
743 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
744 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
745 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
746 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
747 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
748 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
749 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
750 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
751 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
752 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
753 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
754 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
755 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
756 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
757 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
758 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
759 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
760 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
761 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
762 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
763 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
764 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
765 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
766 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
767 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
768 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
769 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
770 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
771 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
772 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
773 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
774 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
775 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
776 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
777 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
778 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
779 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
780 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
781 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
782 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
783 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
784 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
785 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
786 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
787 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
788 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
789 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
790 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
791 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
792 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
793 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
794};
795
796static const uint8_t uvd_it_scaling_table[] = {
797 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
798 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
799 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
800 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
801 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
802 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
803 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
804 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
805 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
806 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
807 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
808 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
809 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
810 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
811};
812
813#endif /* _UVD_MESSAGES_H_ */
diff --git a/tests/amdgpu/vce_ib.h b/tests/amdgpu/vce_ib.h
new file mode 100644
index 00000000..bd0bf943
--- /dev/null
+++ b/tests/amdgpu/vce_ib.h
@@ -0,0 +1,318 @@
1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifndef _vce_ib_h_
25#define _vce_ib_h_
26
27static const uint32_t vce_session[] = {
28 0x0000000c,
29 0x00000001,
30 0x400c0001,
31};
32
33static uint32_t vce_taskinfo[8] = {
34 0x00000020,
35 0x00000002,
36 0xffffffff,
37 0x00000000,
38 0x00000000,
39 0x00000000,
40 0x00000000,
41 0x00000000,
42};
43
44static const uint32_t vce_create[] = {
45 0x00000030,
46 0x01000001,
47 0x00000000,
48 0x00000042,
49 0x0000002a,
50 0x00000000,
51 0x000000a0,
52 0x00000080,
53 0x000000a0,
54 0x000000a0,
55 0x00000010,
56 0x00000000,
57};
58
59static const uint32_t vce_rate_ctrl[] = {
60 0x00000070,
61 0x04000005,
62 0x00000000,
63 0x00000000,
64 0x00000000,
65 0x00000000,
66 0x00000000,
67 0x0000001c,
68 0x0000001c,
69 0x00000000,
70 0x00000000,
71 0x00000000,
72 0x00000000,
73 0x00000000,
74 0x00000000,
75 0x00000000,
76 0x00000000,
77 0x00000000,
78 0x00000000,
79 0x00000033,
80 0x00000000,
81 0x00000000,
82 0x00000000,
83 0x00000000,
84 0x00000000,
85 0x00000000,
86 0x00000000,
87 0x00000000,
88};
89
90static const uint32_t vce_config_ext[] = {
91 0x0000000c,
92 0x04000001,
93 0x00000003,
94};
95
96static const uint32_t vce_motion_est[] = {
97 0x00000068,
98 0x04000007,
99 0x00000001,
100 0x00000001,
101 0x00000000,
102 0x00000000,
103 0x00000000,
104 0x00000000,
105 0x00000010,
106 0x00000010,
107 0x00000010,
108 0x00000010,
109 0x00000000,
110 0x00000000,
111 0x00000000,
112 0x000000fe,
113 0x00000000,
114 0x00000000,
115 0x00000000,
116 0x00000000,
117 0x00000001,
118 0x00000001,
119 0x00000000,
120 0x00000000,
121 0x00000000,
122 0x00000000,
123};
124
125static const uint32_t vce_rdo[] = {
126 0x0000004c,
127 0x04000008,
128 0x00000000,
129 0x00000000,
130 0x00000000,
131 0x00000000,
132 0x00000000,
133 0x00000000,
134 0x00000000,
135 0x00000000,
136 0x00000000,
137 0x00000000,
138 0x00000000,
139 0x00000000,
140 0x00000000,
141 0x00000000,
142 0x00000000,
143 0x00000000,
144 0x00000000,
145};
146
147static const uint32_t vce_pic_ctrl[] = {
148 0x00000074,
149 0x04000002,
150 0x00000000,
151 0x00000000,
152 0x00000000,
153 0x00000000,
154 0x00000000,
155 0x00000000,
156 0x00000000,
157 0x00000000,
158 0x00000000,
159 0x00000000,
160 0x00000aa0,
161 0x00000000,
162 0x00000000,
163 0x00000000,
164 0x00000000,
165 0x00000000,
166 0x00000000,
167 0x00000000,
168 0x00000040,
169 0x00000000,
170 0x00000000,
171 0x00000001,
172 0x00000002,
173 0x00000001,
174 0x00000001,
175 0x00000000,
176 0x00000000,
177};
178
179static const uint32_t vce_feedback[] = {
180 0x00000014,
181 0x05000005,
182 0x00000000,
183 0xffffffff,
184 0x00000001,
185};
186
187static const uint32_t vce_context_buffer[] = {
188 0x00000010,
189 0x05000001,
190 0x00000000,
191 0xffffffff,
192};
193
194static const uint32_t vce_bs_buffer[] = {
195 0x00000014,
196 0x05000004,
197 0x00000000,
198 0xffffffff,
199 0x00154000,
200};
201
202static const uint32_t vce_aux_buffer[] = {
203 0x00000048,
204 0x05000002,
205 0x0000f000,
206 0x00016800,
207 0x0001e000,
208 0x00025800,
209 0x0002d000,
210 0x00034800,
211 0x0003c000,
212 0x00043800,
213 0x00007800,
214 0x00007800,
215 0x00007800,
216 0x00007800,
217 0x00007800,
218 0x00007800,
219 0x00007800,
220 0x00007800,
221};
222
223static uint32_t vce_encode[88] = {
224 0x00000160,
225 0x03000001,
226 0x00000011,
227 0x00000000,
228 0x00154000,
229 0x00000000,
230 0x00000000,
231 0x00000000,
232 0x00000000,
233 0x00000000,
234 0xffffffff,
235 0x00000000,
236 0xffffffff,
237 0x00000080,
238 0x000000a0,
239 0x000000a0,
240 0x00010000,
241 0x00000000,
242 0x00000003,
243 0x00000001,
244 0x00000000,
245 0x00000000,
246 0x00000001,
247 0x00000000,
248 0x00000000,
249 0x00000000,
250 0x00000000,
251 0x00000000,
252 0x00000000,
253 0x00000000,
254 0x00000000,
255 0x00000000,
256 0x00000000,
257 0x00000000,
258 0x00000000,
259 0x00000000,
260 0x00000000,
261 0x00000000,
262 0x00000000,
263 0x00000000,
264 0x00000000,
265 0x00000000,
266 0x00000000,
267 0x00000000,
268 0x00000000,
269 0x00000000,
270 0x00000000,
271 0x00000000,
272 0x00000000,
273 0x00000000,
274 0x00000000,
275 0x00000000,
276 0x00000000,
277 0x00000000,
278 0x00000000,
279 0x00000000,
280 0x00000000,
281 0x00000000,
282 0x00000000,
283 0xffffffff,
284 0xffffffff,
285 0x00000000,
286 0x00000000,
287 0x00000000,
288 0x00000000,
289 0xffffffff,
290 0xffffffff,
291 0x00000000,
292 0x00000000,
293 0x00000000,
294 0x00000000,
295 0xffffffff,
296 0xffffffff,
297 0xffffffff,
298 0xffffffff,
299 0x00000000,
300 0x00000000,
301 0x00000000,
302 0x00000000,
303 0x00000000,
304 0x00000000,
305 0x00000000,
306 0x00000000,
307 0x00000000,
308 0x00000000,
309 0x00000000,
310 0x00000000,
311 0x00000000,
312};
313
314static const uint32_t vce_destroy[] = {
315 0x00000008,
316 0x02000001,
317};
318#endif /*_vce_ib_h*/
diff --git a/tests/amdgpu/vce_tests.c b/tests/amdgpu/vce_tests.c
new file mode 100644
index 00000000..32fc001b
--- /dev/null
+++ b/tests/amdgpu/vce_tests.c
@@ -0,0 +1,493 @@
1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <stdio.h>
29#include <inttypes.h>
30
31#include "CUnit/Basic.h"
32
33#include "util_math.h"
34
35#include "amdgpu_test.h"
36#include "amdgpu_drm.h"
37#include "amdgpu_internal.h"
38
39#include "vce_ib.h"
40#include "frame.h"
41
42#define IB_SIZE 4096
43#define MAX_RESOURCES 16
44
45struct amdgpu_vce_bo {
46 amdgpu_bo_handle handle;
47 amdgpu_va_handle va_handle;
48 uint64_t addr;
49 uint64_t size;
50 uint8_t *ptr;
51};
52
53struct amdgpu_vce_encode {
54 unsigned width;
55 unsigned height;
56 struct amdgpu_vce_bo vbuf;
57 struct amdgpu_vce_bo bs[2];
58 struct amdgpu_vce_bo fb[2];
59 struct amdgpu_vce_bo cpb;
60 unsigned ib_len;
61 bool two_instance;
62};
63
64static amdgpu_device_handle device_handle;
65static uint32_t major_version;
66static uint32_t minor_version;
67static uint32_t family_id;
68
69static amdgpu_context_handle context_handle;
70static amdgpu_bo_handle ib_handle;
71static amdgpu_va_handle ib_va_handle;
72static uint64_t ib_mc_address;
73static uint32_t *ib_cpu;
74
75static struct amdgpu_vce_encode enc;
76static amdgpu_bo_handle resources[MAX_RESOURCES];
77static unsigned num_resources;
78
79static void amdgpu_cs_vce_create(void);
80static void amdgpu_cs_vce_encode(void);
81static void amdgpu_cs_vce_destroy(void);
82
83CU_TestInfo vce_tests[] = {
84 { "VCE create", amdgpu_cs_vce_create },
85 { "VCE encode", amdgpu_cs_vce_encode },
86 { "VCE destroy", amdgpu_cs_vce_destroy },
87 CU_TEST_INFO_NULL,
88};
89
90int suite_vce_tests_init(void)
91{
92 int r;
93
94 r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
95 &minor_version, &device_handle);
96 if (r)
97 return CUE_SINIT_FAILED;
98
99 family_id = device_handle->info.family_id;
100
101 r = amdgpu_cs_ctx_create(device_handle, &context_handle);
102 if (r)
103 return CUE_SINIT_FAILED;
104
105 r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
106 AMDGPU_GEM_DOMAIN_GTT, 0,
107 &ib_handle, (void**)&ib_cpu,
108 &ib_mc_address, &ib_va_handle);
109 if (r)
110 return CUE_SINIT_FAILED;
111
112 memset(&enc, 0, sizeof(struct amdgpu_vce_encode));
113
114 return CUE_SUCCESS;
115}
116
117int suite_vce_tests_clean(void)
118{
119 int r;
120
121 r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
122 ib_mc_address, IB_SIZE);
123 if (r)
124 return CUE_SCLEAN_FAILED;
125
126 r = amdgpu_cs_ctx_free(context_handle);
127 if (r)
128 return CUE_SCLEAN_FAILED;
129
130 r = amdgpu_device_deinitialize(device_handle);
131 if (r)
132 return CUE_SCLEAN_FAILED;
133
134 return CUE_SUCCESS;
135}
136
137static int submit(unsigned ndw, unsigned ip)
138{
139 struct amdgpu_cs_request ibs_request = {0};
140 struct amdgpu_cs_ib_info ib_info = {0};
141 struct amdgpu_cs_fence fence_status = {0};
142 uint32_t expired;
143 int r;
144
145 ib_info.ib_mc_address = ib_mc_address;
146 ib_info.size = ndw;
147
148 ibs_request.ip_type = ip;
149
150 r = amdgpu_bo_list_create(device_handle, num_resources, resources,
151 NULL, &ibs_request.resources);
152 if (r)
153 return r;
154
155 ibs_request.number_of_ibs = 1;
156 ibs_request.ibs = &ib_info;
157 ibs_request.fence_info.handle = NULL;
158
159 r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
160 if (r)
161 return r;
162
163 r = amdgpu_bo_list_destroy(ibs_request.resources);
164 if (r)
165 return r;
166
167 fence_status.context = context_handle;
168 fence_status.ip_type = ip;
169 fence_status.fence = ibs_request.seq_no;
170
171 r = amdgpu_cs_query_fence_status(&fence_status,
172 AMDGPU_TIMEOUT_INFINITE,
173 0, &expired);
174 if (r)
175 return r;
176
177 return 0;
178}
179
180static void alloc_resource(struct amdgpu_vce_bo *vce_bo, unsigned size, unsigned domain)
181{
182 struct amdgpu_bo_alloc_request req = {0};
183 amdgpu_bo_handle buf_handle;
184 amdgpu_va_handle va_handle;
185 uint64_t va = 0;
186 int r;
187
188 req.alloc_size = ALIGN(size, 4096);
189 req.preferred_heap = domain;
190 r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
191 CU_ASSERT_EQUAL(r, 0);
192 r = amdgpu_va_range_alloc(device_handle,
193 amdgpu_gpu_va_range_general,
194 req.alloc_size, 1, 0, &va,
195 &va_handle, 0);
196 CU_ASSERT_EQUAL(r, 0);
197 r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
198 AMDGPU_VA_OP_MAP);
199 CU_ASSERT_EQUAL(r, 0);
200 vce_bo->addr = va;
201 vce_bo->handle = buf_handle;
202 vce_bo->size = req.alloc_size;
203 vce_bo->va_handle = va_handle;
204 r = amdgpu_bo_cpu_map(vce_bo->handle, (void **)&vce_bo->ptr);
205 CU_ASSERT_EQUAL(r, 0);
206 memset(vce_bo->ptr, 0, size);
207 r = amdgpu_bo_cpu_unmap(vce_bo->handle);
208 CU_ASSERT_EQUAL(r, 0);
209}
210
211static void free_resource(struct amdgpu_vce_bo *vce_bo)
212{
213 int r;
214
215 r = amdgpu_bo_va_op(vce_bo->handle, 0, vce_bo->size,
216 vce_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
217 CU_ASSERT_EQUAL(r, 0);
218
219 r = amdgpu_va_range_free(vce_bo->va_handle);
220 CU_ASSERT_EQUAL(r, 0);
221
222 r = amdgpu_bo_free(vce_bo->handle);
223 CU_ASSERT_EQUAL(r, 0);
224 memset(vce_bo, 0, sizeof(*vce_bo));
225}
226
227static void amdgpu_cs_vce_create(void)
228{
229 int len, r;
230
231 enc.width = vce_create[6];
232 enc.height = vce_create[7];
233
234 num_resources = 0;
235 alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
236 resources[num_resources++] = enc.fb[0].handle;
237 resources[num_resources++] = ib_handle;
238
239 len = 0;
240 memcpy(ib_cpu, vce_session, sizeof(vce_session));
241 len += sizeof(vce_session) / 4;
242 memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
243 len += sizeof(vce_taskinfo) / 4;
244 memcpy((ib_cpu + len), vce_create, sizeof(vce_create));
245 len += sizeof(vce_create) / 4;
246 memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
247 ib_cpu[len + 2] = enc.fb[0].addr >> 32;
248 ib_cpu[len + 3] = enc.fb[0].addr;
249 len += sizeof(vce_feedback) / 4;
250
251 r = submit(len, AMDGPU_HW_IP_VCE);
252 CU_ASSERT_EQUAL(r, 0);
253
254 free_resource(&enc.fb[0]);
255}
256
257static void amdgpu_cs_vce_config(void)
258{
259 int len = 0, r;
260
261 memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
262 len += sizeof(vce_session) / 4;
263 memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
264 ib_cpu[len + 3] = 2;
265 ib_cpu[len + 6] = 0xffffffff;
266 len += sizeof(vce_taskinfo) / 4;
267 memcpy((ib_cpu + len), vce_rate_ctrl, sizeof(vce_rate_ctrl));
268 len += sizeof(vce_rate_ctrl) / 4;
269 memcpy((ib_cpu + len), vce_config_ext, sizeof(vce_config_ext));
270 len += sizeof(vce_config_ext) / 4;
271 memcpy((ib_cpu + len), vce_motion_est, sizeof(vce_motion_est));
272 len += sizeof(vce_motion_est) / 4;
273 memcpy((ib_cpu + len), vce_rdo, sizeof(vce_rdo));
274 len += sizeof(vce_rdo) / 4;
275 memcpy((ib_cpu + len), vce_pic_ctrl, sizeof(vce_pic_ctrl));
276 len += sizeof(vce_pic_ctrl) / 4;
277
278 r = submit(len, AMDGPU_HW_IP_VCE);
279 CU_ASSERT_EQUAL(r, 0);
280}
281
282static void amdgpu_cs_vce_encode_idr(struct amdgpu_vce_encode *enc)
283{
284
285 uint64_t luma_offset, chroma_offset;
286 int len = 0, r;
287
288 luma_offset = enc->vbuf.addr;
289 chroma_offset = luma_offset + enc->width * enc->height;
290
291 memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
292 len += sizeof(vce_session) / 4;
293 memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
294 len += sizeof(vce_taskinfo) / 4;
295 memcpy((ib_cpu + len), vce_bs_buffer, sizeof(vce_bs_buffer));
296 ib_cpu[len + 2] = enc->bs[0].addr >> 32;
297 ib_cpu[len + 3] = enc->bs[0].addr;
298 len += sizeof(vce_bs_buffer) / 4;
299 memcpy((ib_cpu + len), vce_context_buffer, sizeof(vce_context_buffer));
300 ib_cpu[len + 2] = enc->cpb.addr >> 32;
301 ib_cpu[len + 3] = enc->cpb.addr;
302 len += sizeof(vce_context_buffer) / 4;
303 memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer));
304 len += sizeof(vce_aux_buffer) / 4;
305 memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
306 ib_cpu[len + 2] = enc->fb[0].addr >> 32;
307 ib_cpu[len + 3] = enc->fb[0].addr;
308 len += sizeof(vce_feedback) / 4;
309 memcpy((ib_cpu + len), vce_encode, sizeof(vce_encode));
310 ib_cpu[len + 9] = luma_offset >> 32;
311 ib_cpu[len + 10] = luma_offset;
312 ib_cpu[len + 11] = chroma_offset >> 32;
313 ib_cpu[len + 12] = chroma_offset;
314 ib_cpu[len + 73] = 0x7800;
315 ib_cpu[len + 74] = 0x7800 + 0x5000;
316 len += sizeof(vce_encode) / 4;
317 enc->ib_len = len;
318 if (!enc->two_instance) {
319 r = submit(len, AMDGPU_HW_IP_VCE);
320 CU_ASSERT_EQUAL(r, 0);
321 }
322}
323
324static void amdgpu_cs_vce_encode_p(struct amdgpu_vce_encode *enc)
325{
326 uint64_t luma_offset, chroma_offset;
327 int len, r;
328
329 len = (enc->two_instance) ? enc->ib_len : 0;
330 luma_offset = enc->vbuf.addr;
331 chroma_offset = luma_offset + enc->width * enc->height;
332
333 if (!enc->two_instance) {
334 memcpy((ib_cpu + len), vce_session, sizeof(vce_session));
335 len += sizeof(vce_session) / 4;
336 }
337 memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
338 len += sizeof(vce_taskinfo) / 4;
339 memcpy((ib_cpu + len), vce_bs_buffer, sizeof(vce_bs_buffer));
340 ib_cpu[len + 2] = enc->bs[1].addr >> 32;
341 ib_cpu[len + 3] = enc->bs[1].addr;
342 len += sizeof(vce_bs_buffer) / 4;
343 memcpy((ib_cpu + len), vce_context_buffer, sizeof(vce_context_buffer));
344 ib_cpu[len + 2] = enc->cpb.addr >> 32;
345 ib_cpu[len + 3] = enc->cpb.addr;
346 len += sizeof(vce_context_buffer) / 4;
347 memcpy((ib_cpu + len), vce_aux_buffer, sizeof(vce_aux_buffer));
348 len += sizeof(vce_aux_buffer) / 4;
349 memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
350 ib_cpu[len + 2] = enc->fb[1].addr >> 32;
351 ib_cpu[len + 3] = enc->fb[1].addr;
352 len += sizeof(vce_feedback) / 4;
353 memcpy((ib_cpu + len), vce_encode, sizeof(vce_encode));
354 ib_cpu[len + 2] = 0;
355 ib_cpu[len + 9] = luma_offset >> 32;
356 ib_cpu[len + 10] = luma_offset;
357 ib_cpu[len + 11] = chroma_offset >> 32;
358 ib_cpu[len + 12] = chroma_offset;
359 ib_cpu[len + 18] = 0;
360 ib_cpu[len + 19] = 0;
361 ib_cpu[len + 56] = 3;
362 ib_cpu[len + 57] = 0;
363 ib_cpu[len + 58] = 0;
364 ib_cpu[len + 59] = 0x7800;
365 ib_cpu[len + 60] = 0x7800 + 0x5000;
366 ib_cpu[len + 73] = 0;
367 ib_cpu[len + 74] = 0x5000;
368 ib_cpu[len + 81] = 1;
369 ib_cpu[len + 82] = 1;
370 len += sizeof(vce_encode) / 4;
371
372 r = submit(len, AMDGPU_HW_IP_VCE);
373 CU_ASSERT_EQUAL(r, 0);
374}
375
376static void check_result(struct amdgpu_vce_encode *enc)
377{
378 uint64_t sum;
379 uint32_t s[2] = {180325, 15946};
380 uint32_t *ptr, size;
381 int i, j, r;
382
383 for (i = 0; i < 2; ++i) {
384 r = amdgpu_bo_cpu_map(enc->fb[i].handle, (void **)&enc->fb[i].ptr);
385 CU_ASSERT_EQUAL(r, 0);
386 ptr = (uint32_t *)enc->fb[i].ptr;
387 size = ptr[4] - ptr[9];
388 r = amdgpu_bo_cpu_unmap(enc->fb[i].handle);
389 CU_ASSERT_EQUAL(r, 0);
390 r = amdgpu_bo_cpu_map(enc->bs[i].handle, (void **)&enc->bs[i].ptr);
391 CU_ASSERT_EQUAL(r, 0);
392 for (j = 0, sum = 0; j < size; ++j)
393 sum += enc->bs[i].ptr[j];
394 CU_ASSERT_EQUAL(sum, s[i]);
395 r = amdgpu_bo_cpu_unmap(enc->bs[i].handle);
396 CU_ASSERT_EQUAL(r, 0);
397 }
398}
399
400static void amdgpu_cs_vce_encode(void)
401{
402 uint32_t vbuf_size, bs_size = 0x154000, cpb_size;
403 int r;
404
405 vbuf_size = enc.width * enc.height * 1.5;
406 cpb_size = vbuf_size * 10;
407 num_resources = 0;
408 alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
409 resources[num_resources++] = enc.fb[0].handle;
410 alloc_resource(&enc.fb[1], 4096, AMDGPU_GEM_DOMAIN_GTT);
411 resources[num_resources++] = enc.fb[1].handle;
412 alloc_resource(&enc.bs[0], bs_size, AMDGPU_GEM_DOMAIN_GTT);
413 resources[num_resources++] = enc.bs[0].handle;
414 alloc_resource(&enc.bs[1], bs_size, AMDGPU_GEM_DOMAIN_GTT);
415 resources[num_resources++] = enc.bs[1].handle;
416 alloc_resource(&enc.vbuf, vbuf_size, AMDGPU_GEM_DOMAIN_VRAM);
417 resources[num_resources++] = enc.vbuf.handle;
418 alloc_resource(&enc.cpb, cpb_size, AMDGPU_GEM_DOMAIN_VRAM);
419 resources[num_resources++] = enc.cpb.handle;
420 resources[num_resources++] = ib_handle;
421
422 r = amdgpu_bo_cpu_map(enc.vbuf.handle, (void **)&enc.vbuf.ptr);
423 CU_ASSERT_EQUAL(r, 0);
424 memcpy(enc.vbuf.ptr, frame, sizeof(frame));
425 r = amdgpu_bo_cpu_unmap(enc.vbuf.handle);
426 CU_ASSERT_EQUAL(r, 0);
427
428 amdgpu_cs_vce_config();
429
430 if (family_id >= AMDGPU_FAMILY_VI) {
431 vce_taskinfo[3] = 3;
432 amdgpu_cs_vce_encode_idr(&enc);
433 amdgpu_cs_vce_encode_p(&enc);
434 check_result(&enc);
435
436 /* two pipes */
437 vce_encode[16] = 0;
438 amdgpu_cs_vce_encode_idr(&enc);
439 amdgpu_cs_vce_encode_p(&enc);
440 check_result(&enc);
441
442 /* two instances */
443 enc.two_instance = true;
444 vce_taskinfo[2] = 0x83;
445 vce_taskinfo[4] = 1;
446 amdgpu_cs_vce_encode_idr(&enc);
447 vce_taskinfo[2] = 0xffffffff;
448 vce_taskinfo[4] = 2;
449 amdgpu_cs_vce_encode_p(&enc);
450 check_result(&enc);
451 } else {
452 vce_taskinfo[3] = 3;
453 vce_encode[16] = 0;
454 amdgpu_cs_vce_encode_idr(&enc);
455 amdgpu_cs_vce_encode_p(&enc);
456 check_result(&enc);
457 }
458
459 free_resource(&enc.fb[0]);
460 free_resource(&enc.fb[1]);
461 free_resource(&enc.bs[0]);
462 free_resource(&enc.bs[1]);
463 free_resource(&enc.vbuf);
464 free_resource(&enc.cpb);
465}
466
467static void amdgpu_cs_vce_destroy(void)
468{
469 int len, r;
470
471 num_resources = 0;
472 alloc_resource(&enc.fb[0], 4096, AMDGPU_GEM_DOMAIN_GTT);
473 resources[num_resources++] = enc.fb[0].handle;
474 resources[num_resources++] = ib_handle;
475
476 len = 0;
477 memcpy(ib_cpu, vce_session, sizeof(vce_session));
478 len += sizeof(vce_session) / 4;
479 memcpy((ib_cpu + len), vce_taskinfo, sizeof(vce_taskinfo));
480 ib_cpu[len + 3] = 1;
481 len += sizeof(vce_taskinfo) / 4;
482 memcpy((ib_cpu + len), vce_feedback, sizeof(vce_feedback));
483 ib_cpu[len + 2] = enc.fb[0].addr >> 32;
484 ib_cpu[len + 3] = enc.fb[0].addr;
485 len += sizeof(vce_feedback) / 4;
486 memcpy((ib_cpu + len), vce_destroy, sizeof(vce_destroy));
487 len += sizeof(vce_destroy) / 4;
488
489 r = submit(len, AMDGPU_HW_IP_VCE);
490 CU_ASSERT_EQUAL(r, 0);
491
492 free_resource(&enc.fb[0]);
493}
diff --git a/tests/auth.c b/tests/auth.c
index 9b6fca94..9147b115 100644
--- a/tests/auth.c
+++ b/tests/auth.c
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28#include <limits.h> 28#include <limits.h>
29#include <sys/ioctl.h>
29#include "drmtest.h" 30#include "drmtest.h"
30 31
31enum auth_event { 32enum auth_event {
diff --git a/tests/dristat.c b/tests/dristat.c
index 4f2ee80a..cca4b03a 100644
--- a/tests/dristat.c
+++ b/tests/dristat.c
@@ -100,6 +100,7 @@ static void getvm(int fd)
100 case DRM_SHM: typename = "SHM"; break; 100 case DRM_SHM: typename = "SHM"; break;
101 case DRM_AGP: typename = "AGP"; break; 101 case DRM_AGP: typename = "AGP"; break;
102 case DRM_SCATTER_GATHER: typename = "SG"; break; 102 case DRM_SCATTER_GATHER: typename = "SG"; break;
103 case DRM_CONSISTENT: typename = "CON"; break;
103 default: typename = "???"; break; 104 default: typename = "???"; break;
104 } 105 }
105 106
@@ -189,9 +190,9 @@ static void printhuman(unsigned long value, const char *name, int mult)
189static void getstats(int fd, int i) 190static void getstats(int fd, int i)
190{ 191{
191 drmStatsT prev, curr; 192 drmStatsT prev, curr;
192 int j; 193 unsigned j;
193 double rate; 194 double rate;
194 195
195 printf(" System statistics:\n"); 196 printf(" System statistics:\n");
196 197
197 if (drmGetStats(fd, &prev)) return; 198 if (drmGetStats(fd, &prev)) return;
@@ -268,7 +269,7 @@ int main(int argc, char **argv)
268 269
269 for (i = 0; i < 16; i++) if (!minor || i == minor) { 270 for (i = 0; i < 16; i++) if (!minor || i == minor) {
270 sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i); 271 sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
271 fd = drmOpenMinor(i, 1, DRM_NODE_RENDER); 272 fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY);
272 if (fd >= 0) { 273 if (fd >= 0) {
273 printf("%s\n", buf); 274 printf("%s\n", buf);
274 if (mask & DRM_BUSID) getbusid(fd); 275 if (mask & DRM_BUSID) getbusid(fd);
diff --git a/tests/drmdevice.c b/tests/drmdevice.c
new file mode 100644
index 00000000..c3363274
--- /dev/null
+++ b/tests/drmdevice.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 2015 Emil Velikov <emil.l.velikov@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 *
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <sys/stat.h>
27#include <fcntl.h>
28#include <unistd.h>
29#include <xf86drm.h>
30
31
32static void
33print_device_info(drmDevicePtr device, int i)
34{
35 printf("device[%i]\n", i);
36 printf("\tavailable_nodes %04x\n", device->available_nodes);
37 printf("\tnodes\n");
38 for (int j = 0; j < DRM_NODE_MAX; j++)
39 if (device->available_nodes & 1 << j)
40 printf("\t\tnodes[%d] %s\n", j, device->nodes[j]);
41
42 printf("\tbustype %04x\n", device->bustype);
43 printf("\tbusinfo\n");
44 if (device->bustype == DRM_BUS_PCI) {
45 printf("\t\tpci\n");
46 printf("\t\t\tdomain\t%04x\n",device->businfo.pci->domain);
47 printf("\t\t\tbu\t%02x\n", device->businfo.pci->bus);
48 printf("\t\t\tde\t%02x\n", device->businfo.pci->dev);
49 printf("\t\t\tfunc\t%1u\n", device->businfo.pci->func);
50
51 printf("\tdeviceinfo\n");
52 printf("\t\tpci\n");
53 printf("\t\t\tvendor_id\t%04x\n", device->deviceinfo.pci->vendor_id);
54 printf("\t\t\tdevice_id\t%04x\n", device->deviceinfo.pci->device_id);
55 printf("\t\t\tsubvendor_id\t%04x\n", device->deviceinfo.pci->subvendor_id);
56 printf("\t\t\tsubdevice_id\t%04x\n", device->deviceinfo.pci->subdevice_id);
57 printf("\t\t\trevision_id\t%02x\n", device->deviceinfo.pci->revision_id);
58 } else {
59 printf("Unknown/unhandled bustype\n");
60 }
61 printf("\n");
62}
63
64int
65main(void)
66{
67 drmDevicePtr *devices;
68 drmDevicePtr device;
69 int fd, ret, max_devices;
70
71 max_devices = drmGetDevices(NULL, 0);
72
73 if (max_devices <= 0) {
74 printf("drmGetDevices() has returned %d\n", max_devices);
75 return -1;
76 }
77
78 devices = calloc(max_devices, sizeof(drmDevicePtr));
79 if (devices == NULL) {
80 printf("Failed to allocate memory for the drmDevicePtr array\n");
81 return -1;
82 }
83
84 ret = drmGetDevices(devices, max_devices);
85 if (ret < 0) {
86 printf("drmGetDevices() returned an error %d\n", ret);
87 free(devices);
88 return -1;
89 }
90
91 for (int i = 0; i < ret; i++) {
92 print_device_info(devices[i], i);
93
94 for (int j = 0; j < DRM_NODE_MAX; j++) {
95 if (devices[i]->available_nodes & 1 << j) {
96 fd = open(devices[i]->nodes[j], O_RDONLY | O_CLOEXEC, 0);
97 if (fd < 0)
98 continue;
99
100 if (drmGetDevice(fd, &device) == 0) {
101 print_device_info(device, -1);
102 drmFreeDevice(&device);
103 }
104 close(fd);
105 }
106 }
107 }
108
109 drmFreeDevices(devices, ret);
110 free(devices);
111 return 0;
112}
diff --git a/tests/drmsl.c b/tests/drmsl.c
new file mode 100644
index 00000000..d0ac0efa
--- /dev/null
+++ b/tests/drmsl.c
@@ -0,0 +1,172 @@
1/* drmsl.c -- Skip list test
2 * Created: Mon May 10 09:28:13 1999 by faith@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
27 *
28 * DESCRIPTION
29 *
30 * This file contains a straightforward skip list implementation.n
31 *
32 * FUTURE ENHANCEMENTS
33 *
34 * REFERENCES
35 *
36 * [Pugh90] William Pugh. Skip Lists: A Probabilistic Alternative to
37 * Balanced Trees. CACM 33(6), June 1990, pp. 668-676.
38 *
39 */
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <sys/time.h>
44
45#include "xf86drm.h"
46
47static void print(void* list)
48{
49 unsigned long key;
50 void *value;
51
52 if (drmSLFirst(list, &key, &value)) {
53 do {
54 printf("key = %5lu, value = %p\n", key, value);
55 } while (drmSLNext(list, &key, &value));
56 }
57}
58
59static double do_time(int size, int iter)
60{
61 void *list;
62 int i, j;
63 unsigned long keys[1000000];
64 unsigned long previous;
65 unsigned long key;
66 void *value;
67 struct timeval start, stop;
68 double usec;
69 void *ranstate;
70
71 list = drmSLCreate();
72 ranstate = drmRandomCreate(12345);
73
74 for (i = 0; i < size; i++) {
75 keys[i] = drmRandom(ranstate);
76 drmSLInsert(list, keys[i], NULL);
77 }
78
79 previous = 0;
80 if (drmSLFirst(list, &key, &value)) {
81 do {
82 if (key <= previous) {
83 printf( "%lu !< %lu\n", previous, key);
84 }
85 previous = key;
86 } while (drmSLNext(list, &key, &value));
87 }
88
89 gettimeofday(&start, NULL);
90 for (j = 0; j < iter; j++) {
91 for (i = 0; i < size; i++) {
92 if (drmSLLookup(list, keys[i], &value))
93 printf("Error %lu %d\n", keys[i], i);
94 }
95 }
96 gettimeofday(&stop, NULL);
97
98 usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
99 - start.tv_sec * 1000000 - start.tv_usec) / (size * iter);
100
101 printf("%0.2f microseconds for list length %d\n", usec, size);
102
103 drmRandomDouble(ranstate);
104 drmSLDestroy(list);
105
106 return usec;
107}
108
109static void print_neighbors(void *list, unsigned long key)
110{
111 unsigned long prev_key = 0;
112 unsigned long next_key = 0;
113 void *prev_value;
114 void *next_value;
115 int retval;
116
117 retval = drmSLLookupNeighbors(list, key,
118 &prev_key, &prev_value,
119 &next_key, &next_value);
120 printf("Neighbors of %5lu: %d %5lu %5lu\n",
121 key, retval, prev_key, next_key);
122}
123
124int main(void)
125{
126 void* list;
127 double usec, usec2, usec3, usec4;
128
129 list = drmSLCreate();
130 printf( "list at %p\n", list);
131
132 print(list);
133 printf("\n==============================\n\n");
134
135 drmSLInsert(list, 123, NULL);
136 drmSLInsert(list, 213, NULL);
137 drmSLInsert(list, 50, NULL);
138 print(list);
139 printf("\n==============================\n\n");
140
141 print_neighbors(list, 0);
142 print_neighbors(list, 50);
143 print_neighbors(list, 51);
144 print_neighbors(list, 123);
145 print_neighbors(list, 200);
146 print_neighbors(list, 213);
147 print_neighbors(list, 256);
148 printf("\n==============================\n\n");
149
150 drmSLDelete(list, 50);
151 print(list);
152 printf("\n==============================\n\n");
153
154 drmSLDump(list);
155 drmSLDestroy(list);
156 printf("\n==============================\n\n");
157
158 usec = do_time(100, 10000);
159 usec2 = do_time(1000, 500);
160 printf("Table size increased by %0.2f, search time increased by %0.2f\n",
161 1000.0/100.0, usec2 / usec);
162
163 usec3 = do_time(10000, 50);
164 printf("Table size increased by %0.2f, search time increased by %0.2f\n",
165 10000.0/100.0, usec3 / usec);
166
167 usec4 = do_time(100000, 4);
168 printf("Table size increased by %0.2f, search time increased by %0.2f\n",
169 100000.0/100.0, usec4 / usec);
170
171 return 0;
172}
diff --git a/tests/drmstat.c b/tests/drmstat.c
index 5935d07a..023aa069 100644
--- a/tests/drmstat.c
+++ b/tests/drmstat.c
@@ -48,11 +48,6 @@
48#endif 48#endif
49#include "xf86drm.h" 49#include "xf86drm.h"
50 50
51/* Support gcc's __FUNCTION__ for people using other compilers */
52#if !defined(__GNUC__) && !defined(__FUNCTION__)
53# define __FUNCTION__ __func__ /* C99 */
54#endif
55
56int sigio_fd; 51int sigio_fd;
57 52
58static double usec(struct timeval *end, struct timeval *start) 53static double usec(struct timeval *end, struct timeval *start)
@@ -81,23 +76,17 @@ static void getversion(int fd)
81 printf( "No driver available\n" ); 76 printf( "No driver available\n" );
82 } 77 }
83} 78}
84
85void handler(int fd, void *oldctx, void *newctx)
86{
87 printf("Got fd %d\n", fd);
88}
89 79
90void process_sigio(char *device) 80static void process_sigio(char *device)
91{ 81{
92 int fd; 82 int fd;
93 83
94 if ((fd = open(device, 0)) < 0) { 84 if ((fd = open(device, 0)) < 0) {
95 drmError(-errno, __FUNCTION__); 85 drmError(-errno, __func__);
96 exit(1); 86 exit(1);
97 } 87 }
98 88
99 sigio_fd = fd; 89 sigio_fd = fd;
100 /* drmInstallSIGIOHandler(fd, handler); */
101 for (;;) sleep(60); 90 for (;;) sleep(60);
102} 91}
103 92
@@ -427,11 +416,4 @@ int main(int argc, char **argv)
427 return r; 416 return r;
428} 417}
429 418
430void DRM_PRINTFLIKE(4, 0)
431xf86VDrvMsgVerb(int scrnIndex, int type, int verb, const char *format,
432 va_list args)
433{
434 vfprintf(stderr, format, args);
435}
436
437int xf86ConfigDRI[10]; 419int xf86ConfigDRI[10];
diff --git a/tests/exynos/Makefile.am b/tests/exynos/Makefile.am
index 92de4e4b..357d6b8c 100644
--- a/tests/exynos/Makefile.am
+++ b/tests/exynos/Makefile.am
@@ -1,19 +1,42 @@
1AM_CFLAGS = \ 1AM_CFLAGS = \
2 $(WARN_CFLAGS)\
2 -I $(top_srcdir)/include/drm \ 3 -I $(top_srcdir)/include/drm \
3 -I $(top_srcdir)/libkms/ \ 4 -I $(top_srcdir)/libkms/ \
4 -I $(top_srcdir)/exynos \ 5 -I $(top_srcdir)/exynos \
5 -I $(top_srcdir) 6 -I $(top_srcdir)
6 7
8bin_PROGRAMS =
9noinst_PROGRAMS =
10
7if HAVE_LIBKMS 11if HAVE_LIBKMS
8if HAVE_INSTALL_TESTS 12if HAVE_INSTALL_TESTS
9bin_PROGRAMS = \ 13bin_PROGRAMS += \
10 exynos_fimg2d_test 14 exynos_fimg2d_test
11else 15else
12noinst_PROGRAMS = \ 16noinst_PROGRAMS += \
13 exynos_fimg2d_test 17 exynos_fimg2d_test
14endif 18endif
15endif 19endif
16 20
21if HAVE_INSTALL_TESTS
22bin_PROGRAMS += \
23 exynos_fimg2d_perf \
24 exynos_fimg2d_event
25else
26noinst_PROGRAMS += \
27 exynos_fimg2d_perf \
28 exynos_fimg2d_event
29endif
30
31exynos_fimg2d_perf_LDADD = \
32 $(top_builddir)/libdrm.la \
33 $(top_builddir)/exynos/libdrm_exynos.la
34
35exynos_fimg2d_event_LDADD = \
36 $(top_builddir)/libdrm.la \
37 $(top_builddir)/exynos/libdrm_exynos.la \
38 -lpthread
39
17exynos_fimg2d_test_LDADD = \ 40exynos_fimg2d_test_LDADD = \
18 $(top_builddir)/libdrm.la \ 41 $(top_builddir)/libdrm.la \
19 $(top_builddir)/libkms/libkms.la \ 42 $(top_builddir)/libkms/libkms.la \
diff --git a/tests/exynos/exynos_fimg2d_event.c b/tests/exynos/exynos_fimg2d_event.c
new file mode 100644
index 00000000..9ed5a307
--- /dev/null
+++ b/tests/exynos/exynos_fimg2d_event.c
@@ -0,0 +1,326 @@
1/*
2 * Copyright (C) 2015 - Tobias Jakobi
3 *
4 * This is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License,
7 * or (at your option) any later version.
8 *
9 * It is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with it. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <unistd.h>
18#include <poll.h>
19
20#include <stdlib.h>
21#include <stdio.h>
22#include <time.h>
23#include <getopt.h>
24
25#include <pthread.h>
26
27#include <xf86drm.h>
28
29#include "exynos_drm.h"
30#include "exynos_drmif.h"
31#include "exynos_fimg2d.h"
32
33struct g2d_job {
34 unsigned int id;
35 unsigned int busy;
36};
37
38struct exynos_evhandler {
39 struct pollfd fds;
40 struct exynos_event_context evctx;
41};
42
43struct threaddata {
44 unsigned int stop;
45 struct exynos_device *dev;
46 struct exynos_evhandler evhandler;
47};
48
49static void g2d_event_handler(int fd, unsigned int cmdlist_no, unsigned int tv_sec,
50 unsigned int tv_usec, void *user_data)
51{
52 struct g2d_job *job = user_data;
53
54 fprintf(stderr, "info: g2d job (id = %u, cmdlist number = %u) finished!\n",
55 job->id, cmdlist_no);
56
57 job->busy = 0;
58}
59
60static void setup_g2d_event_handler(struct exynos_evhandler *evhandler, int fd)
61{
62 evhandler->fds.fd = fd;
63 evhandler->fds.events = POLLIN;
64 evhandler->evctx.base.version = 2;
65 evhandler->evctx.version = 1;
66 evhandler->evctx.g2d_event_handler = g2d_event_handler;
67}
68
69static void* threadfunc(void *arg) {
70 const int timeout = 0;
71 struct threaddata *data;
72
73 data = arg;
74
75 while (1) {
76 if (data->stop) break;
77
78 usleep(500);
79
80 data->evhandler.fds.revents = 0;
81
82 if (poll(&data->evhandler.fds, 1, timeout) < 0)
83 continue;
84
85 if (data->evhandler.fds.revents & (POLLHUP | POLLERR))
86 continue;
87
88 if (data->evhandler.fds.revents & POLLIN)
89 exynos_handle_event(data->dev, &data->evhandler.evctx);
90 }
91
92 pthread_exit(0);
93}
94
95/*
96 * We need to wait until all G2D jobs are finished, otherwise we
97 * potentially remove a BO which the engine still operates on.
98 * This results in the following kernel message:
99 * [drm:exynos_drm_gem_put_dma_addr] *ERROR* failed to lookup gem object.
100 * Also any subsequent BO allocations fail then with:
101 * [drm:exynos_drm_alloc_buf] *ERROR* failed to allocate buffer.
102 */
103static void wait_all_jobs(struct g2d_job* jobs, unsigned num_jobs)
104{
105 unsigned i;
106
107 for (i = 0; i < num_jobs; ++i) {
108 while (jobs[i].busy)
109 usleep(500);
110 }
111
112}
113
114static struct g2d_job* free_job(struct g2d_job* jobs, unsigned num_jobs)
115{
116 unsigned i;
117
118 for (i = 0; i < num_jobs; ++i) {
119 if (jobs[i].busy == 0)
120 return &jobs[i];
121 }
122
123 return NULL;
124}
125
126static int g2d_work(struct g2d_context *ctx, struct g2d_image *img,
127 unsigned num_jobs, unsigned iterations)
128{
129 struct g2d_job *jobs = calloc(num_jobs, sizeof(struct g2d_job));
130 int ret;
131 unsigned i;
132
133 /* setup job ids */
134 for (i = 0; i < num_jobs; ++i)
135 jobs[i].id = i;
136
137 for (i = 0; i < iterations; ++i) {
138 unsigned x, y, w, h;
139
140 struct g2d_job *j = NULL;
141
142 while (1) {
143 j = free_job(jobs, num_jobs);
144
145 if (j)
146 break;
147 else
148 usleep(500);
149 }
150
151 x = rand() % img->width;
152 y = rand() % img->height;
153
154 if (x == (img->width - 1))
155 x -= 1;
156 if (y == (img->height - 1))
157 y -= 1;
158
159 w = rand() % (img->width - x);
160 h = rand() % (img->height - y);
161
162 if (w == 0) w = 1;
163 if (h == 0) h = 1;
164
165 img->color = rand();
166
167 j->busy = 1;
168 g2d_config_event(ctx, j);
169
170 ret = g2d_solid_fill(ctx, img, x, y, w, h);
171
172 if (ret == 0)
173 g2d_exec(ctx);
174
175 if (ret != 0) {
176 fprintf(stderr, "error: iteration %u (x = %u, x = %u, x = %u, x = %u) failed\n",
177 i, x, y, w, h);
178 break;
179 }
180 }
181
182 wait_all_jobs(jobs, num_jobs);
183 free(jobs);
184
185 return 0;
186}
187
188static void usage(const char *name)
189{
190 fprintf(stderr, "usage: %s [-ijwh]\n\n", name);
191
192 fprintf(stderr, "\t-i <number of iterations>\n");
193 fprintf(stderr, "\t-j <number of G2D jobs> (default = 4)\n\n");
194
195 fprintf(stderr, "\t-w <buffer width> (default = 4096)\n");
196 fprintf(stderr, "\t-h <buffer height> (default = 4096)\n");
197
198 exit(0);
199}
200
201int main(int argc, char **argv)
202{
203 int fd, ret, c, parsefail;
204
205 pthread_t event_thread;
206 struct threaddata event_data = {0};
207
208 struct exynos_device *dev;
209 struct g2d_context *ctx;
210 struct exynos_bo *bo;
211
212 struct g2d_image img = {0};
213
214 unsigned int iters = 0, njobs = 4;
215 unsigned int bufw = 4096, bufh = 4096;
216
217 ret = 0;
218 parsefail = 0;
219
220 while ((c = getopt(argc, argv, "i:j:w:h:")) != -1) {
221 switch (c) {
222 case 'i':
223 if (sscanf(optarg, "%u", &iters) != 1)
224 parsefail = 1;
225 break;
226 case 'j':
227 if (sscanf(optarg, "%u", &njobs) != 1)
228 parsefail = 1;
229 break;
230 case 'w':
231 if (sscanf(optarg, "%u", &bufw) != 1)
232 parsefail = 1;
233 break;
234 case 'h':
235 if (sscanf(optarg, "%u", &bufh) != 1)
236 parsefail = 1;
237 break;
238 default:
239 parsefail = 1;
240 break;
241 }
242 }
243
244 if (parsefail || (argc == 1) || (iters == 0))
245 usage(argv[0]);
246
247 if (bufw > 4096 || bufh > 4096) {
248 fprintf(stderr, "error: buffer width/height should be less than 4096.\n");
249 ret = -1;
250
251 goto out;
252 }
253
254 if (bufw == 0 || bufh == 0) {
255 fprintf(stderr, "error: buffer width/height should be non-zero.\n");
256 ret = -1;
257
258 goto out;
259 }
260
261 fd = drmOpen("exynos", NULL);
262 if (fd < 0) {
263 fprintf(stderr, "error: failed to open drm\n");
264 ret = -1;
265
266 goto out;
267 }
268
269 dev = exynos_device_create(fd);
270 if (dev == NULL) {
271 fprintf(stderr, "error: failed to create device\n");
272 ret = -2;
273
274 goto fail;
275 }
276
277 ctx = g2d_init(fd);
278 if (ctx == NULL) {
279 fprintf(stderr, "error: failed to init G2D\n");
280 ret = -3;
281
282 goto g2d_fail;
283 }
284
285 bo = exynos_bo_create(dev, bufw * bufh * 4, 0);
286 if (bo == NULL) {
287 fprintf(stderr, "error: failed to create bo\n");
288 ret = -4;
289
290 goto bo_fail;
291 }
292
293 /* setup g2d image object */
294 img.width = bufw;
295 img.height = bufh;
296 img.stride = bufw * 4;
297 img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
298 img.buf_type = G2D_IMGBUF_GEM;
299 img.bo[0] = bo->handle;
300
301 event_data.dev = dev;
302 setup_g2d_event_handler(&event_data.evhandler, fd);
303
304 pthread_create(&event_thread, NULL, threadfunc, &event_data);
305
306 ret = g2d_work(ctx, &img, njobs, iters);
307 if (ret != 0)
308 fprintf(stderr, "error: g2d_work failed\n");
309
310 event_data.stop = 1;
311 pthread_join(event_thread, NULL);
312
313 exynos_bo_destroy(bo);
314
315bo_fail:
316 g2d_fini(ctx);
317
318g2d_fail:
319 exynos_device_destroy(dev);
320
321fail:
322 drmClose(fd);
323
324out:
325 return ret;
326}
diff --git a/tests/exynos/exynos_fimg2d_perf.c b/tests/exynos/exynos_fimg2d_perf.c
new file mode 100644
index 00000000..1699bba7
--- /dev/null
+++ b/tests/exynos/exynos_fimg2d_perf.c
@@ -0,0 +1,327 @@
1/*
2 * Copyright (C) 2015 - Tobias Jakobi
3 *
4 * This is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation, either version 2 of the License,
7 * or (at your option) any later version.
8 *
9 * It is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with it. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <stdlib.h>
18#include <stdio.h>
19#include <time.h>
20#include <getopt.h>
21#include <errno.h>
22
23#include <xf86drm.h>
24
25#include "exynos_drm.h"
26#include "exynos_drmif.h"
27#include "exynos_fimg2d.h"
28
29static int output_mathematica = 0;
30
31static int fimg2d_perf_simple(struct exynos_bo *bo, struct g2d_context *ctx,
32 unsigned buf_width, unsigned buf_height, unsigned iterations)
33{
34 struct timespec tspec = { 0 };
35 struct g2d_image img = { 0 };
36
37 unsigned long long g2d_time;
38 unsigned i;
39 int ret = 0;
40
41 img.width = buf_width;
42 img.height = buf_height;
43 img.stride = buf_width * 4;
44 img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
45 img.buf_type = G2D_IMGBUF_GEM;
46 img.bo[0] = bo->handle;
47
48 srand(time(NULL));
49
50 printf("starting simple G2D performance test\n");
51 printf("buffer width = %u, buffer height = %u, iterations = %u\n",
52 buf_width, buf_height, iterations);
53
54 if (output_mathematica)
55 putchar('{');
56
57 for (i = 0; i < iterations; ++i) {
58 unsigned x, y, w, h;
59
60 x = rand() % buf_width;
61 y = rand() % buf_height;
62
63 if (x == (buf_width - 1))
64 x -= 1;
65 if (y == (buf_height - 1))
66 y -= 1;
67
68 w = rand() % (buf_width - x);
69 h = rand() % (buf_height - y);
70
71 if (w == 0) w = 1;
72 if (h == 0) h = 1;
73
74 img.color = rand();
75
76 ret = g2d_solid_fill(ctx, &img, x, y, w, h);
77
78 clock_gettime(CLOCK_MONOTONIC, &tspec);
79
80 if (ret == 0)
81 ret = g2d_exec(ctx);
82
83 if (ret != 0) {
84 fprintf(stderr, "error: iteration %u failed (x = %u, y = %u, w = %u, h = %u)\n",
85 i, x, y, w, h);
86 break;
87 } else {
88 struct timespec end = { 0 };
89 clock_gettime(CLOCK_MONOTONIC, &end);
90
91 g2d_time = (end.tv_sec - tspec.tv_sec) * 1000000000ULL;
92 g2d_time += (end.tv_nsec - tspec.tv_nsec);
93
94 if (output_mathematica) {
95 if (i != 0) putchar(',');
96 printf("{%u,%llu}", w * h, g2d_time);
97 } else {
98 printf("num_pixels = %u, usecs = %llu\n", w * h, g2d_time);
99 }
100 }
101 }
102
103 if (output_mathematica)
104 printf("}\n");
105
106 return ret;
107}
108
109static int fimg2d_perf_multi(struct exynos_bo *bo, struct g2d_context *ctx,
110 unsigned buf_width, unsigned buf_height, unsigned iterations, unsigned batch)
111{
112 struct timespec tspec = { 0 };
113 struct g2d_image *images;
114
115 unsigned long long g2d_time;
116 unsigned i, j;
117 int ret = 0;
118
119 images = calloc(batch, sizeof(struct g2d_image));
120 if (images == NULL) {
121 fprintf(stderr, "error: failed to allocate G2D images.\n");
122 return -ENOMEM;
123 }
124
125 for (i = 0; i < batch; ++i) {
126 images[i].width = buf_width;
127 images[i].height = buf_height;
128 images[i].stride = buf_width * 4;
129 images[i].color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
130 images[i].buf_type = G2D_IMGBUF_GEM;
131 images[i].bo[0] = bo->handle;
132 }
133
134 srand(time(NULL));
135
136 printf("starting multi G2D performance test (batch size = %u)\n", batch);
137 printf("buffer width = %u, buffer height = %u, iterations = %u\n",
138 buf_width, buf_height, iterations);
139
140 if (output_mathematica)
141 putchar('{');
142
143 for (i = 0; i < iterations; ++i) {
144 unsigned num_pixels = 0;
145
146 for (j = 0; j < batch; ++j) {
147 unsigned x, y, w, h;
148
149 x = rand() % buf_width;
150 y = rand() % buf_height;
151
152 if (x == (buf_width - 1))
153 x -= 1;
154 if (y == (buf_height - 1))
155 y -= 1;
156
157 w = rand() % (buf_width - x);
158 h = rand() % (buf_height - y);
159
160 if (w == 0) w = 1;
161 if (h == 0) h = 1;
162
163 images[j].color = rand();
164
165 num_pixels += w * h;
166
167 ret = g2d_solid_fill(ctx, &images[j], x, y, w, h);
168 if (ret != 0)
169 break;
170 }
171
172 clock_gettime(CLOCK_MONOTONIC, &tspec);
173
174 if (ret == 0)
175 ret = g2d_exec(ctx);
176
177 if (ret != 0) {
178 fprintf(stderr, "error: iteration %u failed (num_pixels = %u)\n", i, num_pixels);
179 break;
180 } else {
181 struct timespec end = { 0 };
182 clock_gettime(CLOCK_MONOTONIC, &end);
183
184 g2d_time = (end.tv_sec - tspec.tv_sec) * 1000000000ULL;
185 g2d_time += (end.tv_nsec - tspec.tv_nsec);
186
187 if (output_mathematica) {
188 if (i != 0) putchar(',');
189 printf("{%u,%llu}", num_pixels, g2d_time);
190 } else {
191 printf("num_pixels = %u, usecs = %llu\n", num_pixels, g2d_time);
192 }
193 }
194 }
195
196 if (output_mathematica)
197 printf("}\n");
198
199 free(images);
200
201 return ret;
202}
203
204static void usage(const char *name)
205{
206 fprintf(stderr, "usage: %s [-ibwh]\n\n", name);
207
208 fprintf(stderr, "\t-i <number of iterations>\n");
209 fprintf(stderr, "\t-b <size of a batch> (default = 3)\n\n");
210
211 fprintf(stderr, "\t-w <buffer width> (default = 4096)\n");
212 fprintf(stderr, "\t-h <buffer height> (default = 4096)\n\n");
213
214 fprintf(stderr, "\t-M <enable Mathematica styled output>\n");
215
216 exit(0);
217}
218
219int main(int argc, char **argv)
220{
221 int fd, ret, c, parsefail;
222
223 struct exynos_device *dev;
224 struct g2d_context *ctx;
225 struct exynos_bo *bo;
226
227 unsigned int iters = 0, batch = 3;
228 unsigned int bufw = 4096, bufh = 4096;
229
230 ret = 0;
231 parsefail = 0;
232
233 while ((c = getopt(argc, argv, "i:b:w:h:M")) != -1) {
234 switch (c) {
235 case 'i':
236 if (sscanf(optarg, "%u", &iters) != 1)
237 parsefail = 1;
238 break;
239 case 'b':
240 if (sscanf(optarg, "%u", &batch) != 1)
241 parsefail = 1;
242 break;
243 case 'w':
244 if (sscanf(optarg, "%u", &bufw) != 1)
245 parsefail = 1;
246 break;
247 case 'h':
248 if (sscanf(optarg, "%u", &bufh) != 1)
249 parsefail = 1;
250 break;
251 case 'M':
252 output_mathematica = 1;
253 break;
254 default:
255 parsefail = 1;
256 break;
257 }
258 }
259
260 if (parsefail || (argc == 1) || (iters == 0))
261 usage(argv[0]);
262
263 if (bufw < 2 || bufw > 4096 || bufh < 2 || bufh > 4096) {
264 fprintf(stderr, "error: buffer width/height should be in the range 2 to 4096.\n");
265 ret = -1;
266
267 goto out;
268 }
269
270 if (bufw == 0 || bufh == 0) {
271 fprintf(stderr, "error: buffer width/height should be non-zero.\n");
272 ret = -1;
273
274 goto out;
275 }
276
277 fd = drmOpen("exynos", NULL);
278 if (fd < 0) {
279 fprintf(stderr, "error: failed to open drm\n");
280 ret = -1;
281
282 goto out;
283 }
284
285 dev = exynos_device_create(fd);
286 if (dev == NULL) {
287 fprintf(stderr, "error: failed to create device\n");
288 ret = -2;
289
290 goto fail;
291 }
292
293 ctx = g2d_init(fd);
294 if (ctx == NULL) {
295 fprintf(stderr, "error: failed to init G2D\n");
296 ret = -3;
297
298 goto g2d_fail;
299 }
300
301 bo = exynos_bo_create(dev, bufw * bufh * 4, 0);
302 if (bo == NULL) {
303 fprintf(stderr, "error: failed to create bo\n");
304 ret = -4;
305
306 goto bo_fail;
307 }
308
309 ret = fimg2d_perf_simple(bo, ctx, bufw, bufh, iters);
310
311 if (ret == 0)
312 ret = fimg2d_perf_multi(bo, ctx, bufw, bufh, iters, batch);
313
314 exynos_bo_destroy(bo);
315
316bo_fail:
317 g2d_fini(ctx);
318
319g2d_fail:
320 exynos_device_destroy(dev);
321
322fail:
323 drmClose(fd);
324
325out:
326 return ret;
327}
diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c
index c6bd5589..797fb6eb 100644
--- a/tests/exynos/exynos_fimg2d_test.c
+++ b/tests/exynos/exynos_fimg2d_test.c
@@ -18,6 +18,8 @@
18#include <stdio.h> 18#include <stdio.h>
19#include <string.h> 19#include <string.h>
20#include <errno.h> 20#include <errno.h>
21#include <time.h>
22#include <unistd.h>
21 23
22#include <sys/mman.h> 24#include <sys/mman.h>
23#include <linux/stddef.h> 25#include <linux/stddef.h>
@@ -29,48 +31,18 @@
29 31
30#include "exynos_drm.h" 32#include "exynos_drm.h"
31#include "exynos_drmif.h" 33#include "exynos_drmif.h"
32#include "fimg2d.h" 34#include "exynos_fimg2d.h"
33 35
34#define DRM_MODULE_NAME "exynos" 36#define DRM_MODULE_NAME "exynos"
35#define MAX_TEST_CASE 8
36 37
37static unsigned int screen_width, screen_height; 38static unsigned int screen_width, screen_height;
38 39
39/*
40 * A structure to test fimg2d hw.
41 *
42 * @solid_fild: fill given color data to source buffer.
43 * @copy: copy source to destination buffer.
44 * @copy_with_scale: copy source to destination buffer scaling up or
45 * down properly.
46 * @blend: blend source to destination buffer.
47 */
48struct fimg2d_test_case {
49 int (*solid_fill)(struct exynos_device *dev, struct exynos_bo *dst);
50 int (*copy)(struct exynos_device *dev, struct exynos_bo *src,
51 struct exynos_bo *dst, enum e_g2d_buf_type);
52 int (*copy_with_scale)(struct exynos_device *dev,
53 struct exynos_bo *src, struct exynos_bo *dst,
54 enum e_g2d_buf_type);
55 int (*blend)(struct exynos_device *dev,
56 struct exynos_bo *src, struct exynos_bo *dst,
57 enum e_g2d_buf_type);
58};
59
60struct connector { 40struct connector {
61 uint32_t id; 41 uint32_t id;
62 char mode_str[64]; 42 char mode_str[64];
63 char format_str[5];
64 unsigned int fourcc;
65 drmModeModeInfo *mode; 43 drmModeModeInfo *mode;
66 drmModeEncoder *encoder; 44 drmModeEncoder *encoder;
67 int crtc; 45 int crtc;
68 int pipe;
69 int plane_zpos;
70 unsigned int fb_id[2], current_fb_id;
71 struct timeval start;
72
73 int swap_count;
74}; 46};
75 47
76static void connector_find_mode(int fd, struct connector *c, 48static void connector_find_mode(int fd, struct connector *c,
@@ -140,37 +112,6 @@ static void connector_find_mode(int fd, struct connector *c,
140 c->crtc = c->encoder->crtc_id; 112 c->crtc = c->encoder->crtc_id;
141} 113}
142 114
143static int connector_find_plane(int fd, unsigned int *plane_id)
144{
145 drmModePlaneRes *plane_resources;
146 drmModePlane *ovr;
147 int i;
148
149 plane_resources = drmModeGetPlaneResources(fd);
150 if (!plane_resources) {
151 fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
152 strerror(errno));
153 return -1;
154 }
155
156 for (i = 0; i < plane_resources->count_planes; i++) {
157 plane_id[i] = 0;
158
159 ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
160 if (!ovr) {
161 fprintf(stderr, "drmModeGetPlane failed: %s\n",
162 strerror(errno));
163 continue;
164 }
165
166 if (ovr->possible_crtcs & (1 << 0))
167 plane_id[i] = ovr->plane_id;
168 drmModeFreePlane(ovr);
169 }
170
171 return 0;
172}
173
174static int drm_set_crtc(struct exynos_device *dev, struct connector *c, 115static int drm_set_crtc(struct exynos_device *dev, struct connector *c,
175 unsigned int fb_id) 116 unsigned int fb_id)
176{ 117{
@@ -178,14 +119,9 @@ static int drm_set_crtc(struct exynos_device *dev, struct connector *c,
178 119
179 ret = drmModeSetCrtc(dev->fd, c->crtc, 120 ret = drmModeSetCrtc(dev->fd, c->crtc,
180 fb_id, 0, 0, &c->id, 1, c->mode); 121 fb_id, 0, 0, &c->id, 1, c->mode);
181 if (ret) { 122 if (ret)
182 drmMsg("failed to set mode: %s\n", strerror(errno)); 123 drmMsg("failed to set mode: %s\n", strerror(errno));
183 goto err;
184 }
185
186 return 0;
187 124
188err:
189 return ret; 125 return ret;
190} 126}
191 127
@@ -207,15 +143,50 @@ static struct exynos_bo *exynos_create_buffer(struct exynos_device *dev,
207 return bo; 143 return bo;
208} 144}
209 145
146/* Allocate buffer and fill it with checkerboard pattern, where the tiles *
147 * have a random color. The caller has to free the buffer. */
148static void *create_checkerboard_pattern(unsigned int num_tiles_x,
149 unsigned int num_tiles_y, unsigned int tile_size)
150{
151 unsigned int *buf;
152 unsigned int x, y, i, j;
153 const unsigned int stride = num_tiles_x * tile_size;
154
155 if (posix_memalign((void*)&buf, 64, num_tiles_y * tile_size * stride * 4) != 0)
156 return NULL;
157
158 for (x = 0; x < num_tiles_x; ++x) {
159 for (y = 0; y < num_tiles_y; ++y) {
160 const unsigned int color = 0xff000000 + (random() & 0xffffff);
161
162 for (i = 0; i < tile_size; ++i) {
163 for (j = 0; j < tile_size; ++j) {
164 buf[x * tile_size + y * stride * tile_size + i + j * stride] = color;
165 }
166 }
167 }
168 }
169
170 return buf;
171}
172
210static void exynos_destroy_buffer(struct exynos_bo *bo) 173static void exynos_destroy_buffer(struct exynos_bo *bo)
211{ 174{
212 exynos_bo_destroy(bo); 175 exynos_bo_destroy(bo);
213} 176}
214 177
178static void wait_for_user_input(int last)
179{
180 printf("press <ENTER> to %s\n", last ? "exit test application" :
181 "skip to next test");
182
183 getchar();
184}
185
215static int g2d_solid_fill_test(struct exynos_device *dev, struct exynos_bo *dst) 186static int g2d_solid_fill_test(struct exynos_device *dev, struct exynos_bo *dst)
216{ 187{
217 struct g2d_context *ctx; 188 struct g2d_context *ctx;
218 struct g2d_image img; 189 struct g2d_image img = {0};
219 unsigned int count, img_w, img_h; 190 unsigned int count, img_w, img_h;
220 int ret = 0; 191 int ret = 0;
221 192
@@ -223,10 +194,9 @@ static int g2d_solid_fill_test(struct exynos_device *dev, struct exynos_bo *dst)
223 if (!ctx) 194 if (!ctx)
224 return -EFAULT; 195 return -EFAULT;
225 196
226 memset(&img, 0, sizeof(struct g2d_image));
227 img.bo[0] = dst->handle; 197 img.bo[0] = dst->handle;
228 198
229 printf("soild fill test.\n"); 199 printf("solid fill test.\n");
230 200
231 srand(time(NULL)); 201 srand(time(NULL));
232 img_w = screen_width; 202 img_w = screen_width;
@@ -266,8 +236,7 @@ static int g2d_copy_test(struct exynos_device *dev, struct exynos_bo *src,
266 enum e_g2d_buf_type type) 236 enum e_g2d_buf_type type)
267{ 237{
268 struct g2d_context *ctx; 238 struct g2d_context *ctx;
269 struct g2d_image src_img, dst_img; 239 struct g2d_image src_img = {0}, dst_img = {0};
270 unsigned int count;
271 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h; 240 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
272 unsigned long userptr, size; 241 unsigned long userptr, size;
273 int ret; 242 int ret;
@@ -276,8 +245,6 @@ static int g2d_copy_test(struct exynos_device *dev, struct exynos_bo *src,
276 if (!ctx) 245 if (!ctx)
277 return -EFAULT; 246 return -EFAULT;
278 247
279 memset(&src_img, 0, sizeof(struct g2d_image));
280 memset(&dst_img, 0, sizeof(struct g2d_image));
281 dst_img.bo[0] = dst->handle; 248 dst_img.bo[0] = dst->handle;
282 249
283 src_x = 0; 250 src_x = 0;
@@ -303,9 +270,10 @@ static int g2d_copy_test(struct exynos_device *dev, struct exynos_bo *src,
303 src_img.user_ptr[0].userptr = userptr; 270 src_img.user_ptr[0].userptr = userptr;
304 src_img.user_ptr[0].size = size; 271 src_img.user_ptr[0].size = size;
305 break; 272 break;
273 case G2D_IMGBUF_COLOR:
306 default: 274 default:
307 type = G2D_IMGBUF_GEM; 275 ret = -EFAULT;
308 break; 276 goto fail;
309 } 277 }
310 278
311 printf("copy test with %s.\n", 279 printf("copy test with %s.\n",
@@ -339,20 +307,144 @@ err_free_userptr:
339 if (userptr) 307 if (userptr)
340 free((void *)userptr); 308 free((void *)userptr);
341 309
310fail:
342 g2d_fini(ctx); 311 g2d_fini(ctx);
343 312
344 return ret; 313 return ret;
345} 314}
346 315
316static int g2d_move_test(struct exynos_device *dev,
317 struct exynos_bo *tmp,
318 struct exynos_bo *buf,
319 enum e_g2d_buf_type type)
320{
321 struct g2d_context *ctx;
322 struct g2d_image img = {0}, tmp_img = {0};
323 unsigned int img_w, img_h, count;
324 int cur_x, cur_y;
325 void *checkerboard;
326 int ret;
327
328 static const struct g2d_step {
329 int x, y;
330 } steps[] = {
331 { 1, 0}, { 0, 1},
332 {-1, 0}, { 0, -1},
333 { 1, 1}, {-1, -1},
334 { 1, -1}, {-1, 1},
335 { 2, 1}, { 1, 2},
336 {-2, -1}, {-1, -2},
337 { 2, -1}, { 1, -2},
338 {-2, 1}, {-1, 2}
339 };
340 static const unsigned int num_steps =
341 sizeof(steps) / sizeof(struct g2d_step);
342
343 ctx = g2d_init(dev->fd);
344 if (!ctx)
345 return -EFAULT;
346
347 img.bo[0] = buf->handle;
348
349 /* create pattern of half the screen size */
350 checkerboard = create_checkerboard_pattern(screen_width / 64, screen_height / 64, 32);
351 if (!checkerboard) {
352 ret = -EFAULT;
353 goto fail;
354 }
355
356 img_w = (screen_width / 64) * 32;
357 img_h = (screen_height / 64) * 32;
358
359 switch (type) {
360 case G2D_IMGBUF_GEM:
361 memcpy(tmp->vaddr, checkerboard, img_w * img_h * 4);
362 tmp_img.bo[0] = tmp->handle;
363 break;
364 case G2D_IMGBUF_USERPTR:
365 tmp_img.user_ptr[0].userptr = (unsigned long)checkerboard;
366 tmp_img.user_ptr[0].size = img_w * img_h * 4;
367 break;
368 case G2D_IMGBUF_COLOR:
369 default:
370 ret = -EFAULT;
371 goto fail;
372 }
373
374 /* solid fill framebuffer with white color */
375 img.width = screen_width;
376 img.height = screen_height;
377 img.stride = screen_width * 4;
378 img.buf_type = G2D_IMGBUF_GEM;
379 img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
380 img.color = 0xffffffff;
381
382 /* put checkerboard pattern in the center of the framebuffer */
383 cur_x = (screen_width - img_w) / 2;
384 cur_y = (screen_height - img_h) / 2;
385 tmp_img.width = img_w;
386 tmp_img.height = img_h;
387 tmp_img.stride = img_w * 4;
388 tmp_img.buf_type = type;
389 tmp_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
390
391 ret = g2d_solid_fill(ctx, &img, 0, 0, screen_width, screen_height) ||
392 g2d_copy(ctx, &tmp_img, &img, 0, 0, cur_x, cur_y, img_w, img_h);
393
394 if (!ret)
395 ret = g2d_exec(ctx);
396 if (ret < 0)
397 goto fail;
398
399 printf("move test with %s.\n",
400 type == G2D_IMGBUF_GEM ? "gem" : "userptr");
401
402 srand(time(NULL));
403 for (count = 0; count < 256; ++count) {
404 const struct g2d_step *s;
405
406 /* select step and validate it */
407 while (1) {
408 s = &steps[random() % num_steps];
409
410 if (cur_x + s->x < 0 || cur_y + s->y < 0 ||
411 cur_x + img_w + s->x >= screen_width ||
412 cur_y + img_h + s->y >= screen_height)
413 continue;
414 else
415 break;
416 }
417
418 ret = g2d_move(ctx, &img, cur_x, cur_y, cur_x + s->x, cur_y + s->y,
419 img_w, img_h);
420 if (!ret)
421 ret = g2d_exec(ctx);
422
423 if (ret < 0)
424 goto fail;
425
426 cur_x += s->x;
427 cur_y += s->y;
428
429 usleep(100000);
430 }
431
432fail:
433 g2d_fini(ctx);
434
435 free(checkerboard);
436
437 return ret;
438}
439
347static int g2d_copy_with_scale_test(struct exynos_device *dev, 440static int g2d_copy_with_scale_test(struct exynos_device *dev,
348 struct exynos_bo *src, 441 struct exynos_bo *src,
349 struct exynos_bo *dst, 442 struct exynos_bo *dst,
350 enum e_g2d_buf_type type) 443 enum e_g2d_buf_type type)
351{ 444{
352 struct g2d_context *ctx; 445 struct g2d_context *ctx;
353 struct g2d_image src_img, dst_img; 446 struct g2d_image src_img = {0}, dst_img = {0};
354 unsigned int count; 447 unsigned int src_x, src_y, img_w, img_h;
355 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
356 unsigned long userptr, size; 448 unsigned long userptr, size;
357 int ret; 449 int ret;
358 450
@@ -360,14 +452,10 @@ static int g2d_copy_with_scale_test(struct exynos_device *dev,
360 if (!ctx) 452 if (!ctx)
361 return -EFAULT; 453 return -EFAULT;
362 454
363 memset(&src_img, 0, sizeof(struct g2d_image));
364 memset(&dst_img, 0, sizeof(struct g2d_image));
365 dst_img.bo[0] = dst->handle; 455 dst_img.bo[0] = dst->handle;
366 456
367 src_x = 0; 457 src_x = 0;
368 src_y = 0; 458 src_y = 0;
369 dst_x = 0;
370 dst_y = 0;
371 img_w = screen_width; 459 img_w = screen_width;
372 img_h = screen_height; 460 img_h = screen_height;
373 461
@@ -387,9 +475,10 @@ static int g2d_copy_with_scale_test(struct exynos_device *dev,
387 src_img.user_ptr[0].userptr = userptr; 475 src_img.user_ptr[0].userptr = userptr;
388 src_img.user_ptr[0].size = size; 476 src_img.user_ptr[0].size = size;
389 break; 477 break;
478 case G2D_IMGBUF_COLOR:
390 default: 479 default:
391 type = G2D_IMGBUF_GEM; 480 ret = -EFAULT;
392 break; 481 goto fail;
393 } 482 }
394 483
395 printf("copy and scale test with %s.\n", 484 printf("copy and scale test with %s.\n",
@@ -428,6 +517,7 @@ err_free_userptr:
428 if (userptr) 517 if (userptr)
429 free((void *)userptr); 518 free((void *)userptr);
430 519
520fail:
431 g2d_fini(ctx); 521 g2d_fini(ctx);
432 522
433 return 0; 523 return 0;
@@ -439,8 +529,7 @@ static int g2d_blend_test(struct exynos_device *dev,
439 enum e_g2d_buf_type type) 529 enum e_g2d_buf_type type)
440{ 530{
441 struct g2d_context *ctx; 531 struct g2d_context *ctx;
442 struct g2d_image src_img, dst_img; 532 struct g2d_image src_img = {0}, dst_img = {0};
443 unsigned int count;
444 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h; 533 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
445 unsigned long userptr, size; 534 unsigned long userptr, size;
446 int ret; 535 int ret;
@@ -449,8 +538,6 @@ static int g2d_blend_test(struct exynos_device *dev,
449 if (!ctx) 538 if (!ctx)
450 return -EFAULT; 539 return -EFAULT;
451 540
452 memset(&src_img, 0, sizeof(struct g2d_image));
453 memset(&dst_img, 0, sizeof(struct g2d_image));
454 dst_img.bo[0] = dst->handle; 541 dst_img.bo[0] = dst->handle;
455 542
456 src_x = 0; 543 src_x = 0;
@@ -476,9 +563,10 @@ static int g2d_blend_test(struct exynos_device *dev,
476 src_img.user_ptr[0].userptr = userptr; 563 src_img.user_ptr[0].userptr = userptr;
477 src_img.user_ptr[0].size = size; 564 src_img.user_ptr[0].size = size;
478 break; 565 break;
566 case G2D_IMGBUF_COLOR:
479 default: 567 default:
480 type = G2D_IMGBUF_GEM; 568 ret = -EFAULT;
481 break; 569 goto fail;
482 } 570 }
483 571
484 printf("blend test with %s.\n", 572 printf("blend test with %s.\n",
@@ -528,17 +616,90 @@ err_free_userptr:
528 if (userptr) 616 if (userptr)
529 free((void *)userptr); 617 free((void *)userptr);
530 618
619fail:
531 g2d_fini(ctx); 620 g2d_fini(ctx);
532 621
533 return 0; 622 return 0;
534} 623}
535 624
536static struct fimg2d_test_case test_case = { 625static int g2d_checkerboard_test(struct exynos_device *dev,
537 .solid_fill = &g2d_solid_fill_test, 626 struct exynos_bo *src,
538 .copy = &g2d_copy_test, 627 struct exynos_bo *dst,
539 .copy_with_scale = &g2d_copy_with_scale_test, 628 enum e_g2d_buf_type type)
540 .blend = &g2d_blend_test, 629{
541}; 630 struct g2d_context *ctx;
631 struct g2d_image src_img = {0}, dst_img = {0};
632 unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
633 void *checkerboard = NULL;
634 int ret;
635
636 ctx = g2d_init(dev->fd);
637 if (!ctx)
638 return -EFAULT;
639
640 dst_img.bo[0] = dst->handle;
641
642 src_x = 0;
643 src_y = 0;
644 dst_x = 0;
645 dst_y = 0;
646
647 checkerboard = create_checkerboard_pattern(screen_width / 32, screen_height / 32, 32);
648 if (checkerboard == NULL) {
649 ret = -1;
650 goto fail;
651 }
652
653 img_w = screen_width - (screen_width % 32);
654 img_h = screen_height - (screen_height % 32);
655
656 switch (type) {
657 case G2D_IMGBUF_GEM:
658 memcpy(src->vaddr, checkerboard, img_w * img_h * 4);
659 src_img.bo[0] = src->handle;
660 break;
661 case G2D_IMGBUF_USERPTR:
662 src_img.user_ptr[0].userptr = (unsigned long)checkerboard;
663 src_img.user_ptr[0].size = img_w * img_h * 4;
664 break;
665 case G2D_IMGBUF_COLOR:
666 default:
667 ret = -EFAULT;
668 goto fail;
669 }
670
671 printf("checkerboard test with %s.\n",
672 type == G2D_IMGBUF_GEM ? "gem" : "userptr");
673
674 src_img.width = img_w;
675 src_img.height = img_h;
676 src_img.stride = src_img.width * 4;
677 src_img.buf_type = type;
678 src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
679
680 dst_img.width = screen_width;
681 dst_img.height = screen_height;
682 dst_img.stride = dst_img.width * 4;
683 dst_img.buf_type = G2D_IMGBUF_GEM;
684 dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
685 src_img.color = 0xff000000;
686 ret = g2d_solid_fill(ctx, &dst_img, src_x, src_y, screen_width, screen_height);
687 if (ret < 0)
688 goto fail;
689
690 ret = g2d_copy(ctx, &src_img, &dst_img, src_x, src_y, dst_x, dst_y,
691 img_w, img_h);
692 if (ret < 0)
693 goto fail;
694
695 g2d_exec(ctx);
696
697fail:
698 free(checkerboard);
699 g2d_fini(ctx);
700
701 return ret;
702}
542 703
543static void usage(char *name) 704static void usage(char *name)
544{ 705{
@@ -555,7 +716,6 @@ int main(int argc, char **argv)
555 struct exynos_device *dev; 716 struct exynos_device *dev;
556 struct exynos_bo *bo, *src; 717 struct exynos_bo *bo, *src;
557 struct connector con; 718 struct connector con;
558 char *modeset = NULL;
559 unsigned int fb_id; 719 unsigned int fb_id;
560 uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; 720 uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
561 drmModeRes *resources; 721 drmModeRes *resources;
@@ -571,7 +731,6 @@ int main(int argc, char **argv)
571 while ((c = getopt(argc, argv, optstr)) != -1) { 731 while ((c = getopt(argc, argv, optstr)) != -1) {
572 switch (c) { 732 switch (c) {
573 case 's': 733 case 's':
574 modeset = strdup(optarg);
575 con.crtc = -1; 734 con.crtc = -1;
576 if (sscanf(optarg, "%d:0x%64s", 735 if (sscanf(optarg, "%d:0x%64s",
577 &con.id, 736 &con.id,
@@ -584,7 +743,7 @@ int main(int argc, char **argv)
584 break; 743 break;
585 default: 744 default:
586 usage(argv[0]); 745 usage(argv[0]);
587 return -EINVAL; 746 break;
588 } 747 }
589 } 748 }
590 749
@@ -611,10 +770,22 @@ int main(int argc, char **argv)
611 connector_find_mode(dev->fd, &con, resources); 770 connector_find_mode(dev->fd, &con, resources);
612 drmModeFreeResources(resources); 771 drmModeFreeResources(resources);
613 772
773 if (!con.mode) {
774 fprintf(stderr, "failed to find usable connector\n");
775 ret = -EFAULT;
776 goto err_drm_close;
777 }
778
614 screen_width = con.mode->hdisplay; 779 screen_width = con.mode->hdisplay;
615 screen_height = con.mode->vdisplay; 780 screen_height = con.mode->vdisplay;
616 781
617 printf("screen width = %d, screen height = %d\n", screen_width, 782 if (screen_width == 0 || screen_height == 0) {
783 fprintf(stderr, "failed to find sane resolution on connector\n");
784 ret = -EFAULT;
785 goto err_drm_close;
786 }
787
788 printf("screen width = %d, screen height = %d\n", screen_width,
618 screen_height); 789 screen_height);
619 790
620 bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0); 791 bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
@@ -628,26 +799,24 @@ int main(int argc, char **argv)
628 offsets[0] = 0; 799 offsets[0] = 0;
629 800
630 ret = drmModeAddFB2(dev->fd, screen_width, screen_height, 801 ret = drmModeAddFB2(dev->fd, screen_width, screen_height,
631 DRM_FORMAT_RGBA8888, handles, 802 DRM_FORMAT_XRGB8888, handles,
632 pitches, offsets, &fb_id, 0); 803 pitches, offsets, &fb_id, 0);
633 if (ret < 0) 804 if (ret < 0)
634 goto err_destroy_buffer; 805 goto err_destroy_buffer;
635 806
636 con.plane_zpos = -1;
637
638 memset(bo->vaddr, 0xff, screen_width * screen_height * 4); 807 memset(bo->vaddr, 0xff, screen_width * screen_height * 4);
639 808
640 ret = drm_set_crtc(dev, &con, fb_id); 809 ret = drm_set_crtc(dev, &con, fb_id);
641 if (ret < 0) 810 if (ret < 0)
642 goto err_rm_fb; 811 goto err_rm_fb;
643 812
644 ret = test_case.solid_fill(dev, bo); 813 ret = g2d_solid_fill_test(dev, bo);
645 if (ret < 0) { 814 if (ret < 0) {
646 fprintf(stderr, "failed to solid fill operation.\n"); 815 fprintf(stderr, "failed to solid fill operation.\n");
647 goto err_rm_fb; 816 goto err_rm_fb;
648 } 817 }
649 818
650 getchar(); 819 wait_for_user_input(0);
651 820
652 src = exynos_create_buffer(dev, screen_width * screen_height * 4, 0); 821 src = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
653 if (!src) { 822 if (!src) {
@@ -655,27 +824,53 @@ int main(int argc, char **argv)
655 goto err_rm_fb; 824 goto err_rm_fb;
656 } 825 }
657 826
658 ret = test_case.copy(dev, src, bo, G2D_IMGBUF_GEM); 827 ret = g2d_copy_test(dev, src, bo, G2D_IMGBUF_GEM);
659 if (ret < 0) { 828 if (ret < 0) {
660 fprintf(stderr, "failed to test copy operation.\n"); 829 fprintf(stderr, "failed to test copy operation.\n");
661 goto err_free_src; 830 goto err_free_src;
662 } 831 }
663 832
664 getchar(); 833 wait_for_user_input(0);
665 834
666 ret = test_case.copy_with_scale(dev, src, bo, G2D_IMGBUF_GEM); 835 ret = g2d_move_test(dev, src, bo, G2D_IMGBUF_GEM);
836 if (ret < 0) {
837 fprintf(stderr, "failed to test move operation.\n");
838 goto err_free_src;
839 }
840
841 wait_for_user_input(0);
842
843 ret = g2d_copy_with_scale_test(dev, src, bo, G2D_IMGBUF_GEM);
667 if (ret < 0) { 844 if (ret < 0) {
668 fprintf(stderr, "failed to test copy and scale operation.\n"); 845 fprintf(stderr, "failed to test copy and scale operation.\n");
669 goto err_free_src; 846 goto err_free_src;
670 } 847 }
671 848
672 getchar(); 849 wait_for_user_input(0);
673 850
674 ret = test_case.blend(dev, src, bo, G2D_IMGBUF_USERPTR); 851 ret = g2d_checkerboard_test(dev, src, bo, G2D_IMGBUF_GEM);
852 if (ret < 0) {
853 fprintf(stderr, "failed to issue checkerboard test.\n");
854 goto err_free_src;
855 }
856
857 wait_for_user_input(1);
858
859 /*
860 * The blend test uses the userptr functionality of exynos-drm, which
861 * is currently not safe to use. If the kernel hasn't been build with
862 * exynos-iommu support, then the blend test is going to produce (kernel)
863 * memory corruption, eventually leading to a system crash.
864 *
865 * Disable the test for now, until the kernel code has been sanitized.
866 */
867#if 0
868 ret = g2d_blend_test(dev, src, bo, G2D_IMGBUF_USERPTR);
675 if (ret < 0) 869 if (ret < 0)
676 fprintf(stderr, "failed to test blend operation.\n"); 870 fprintf(stderr, "failed to test blend operation.\n");
677 871
678 getchar(); 872 getchar();
873#endif
679 874
680err_free_src: 875err_free_src:
681 if (src) 876 if (src)
diff --git a/tests/gem_basic.c b/tests/gem_basic.c
deleted file mode 100644
index 4e4b6cbd..00000000
--- a/tests/gem_basic.c
+++ /dev/null
@@ -1,102 +0,0 @@
1/*
2 * Copyright © 2008 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <assert.h>
32#include <fcntl.h>
33#include <inttypes.h>
34#include <errno.h>
35#include <sys/stat.h>
36#include "drm.h"
37#include "i915_drm.h"
38
39static void
40test_bad_close(int fd)
41{
42 struct drm_gem_close close;
43 int ret;
44
45 printf("Testing error return on bad close ioctl.\n");
46
47 close.handle = 0x10101010;
48 ret = ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close);
49
50 assert(ret == -1 && errno == EINVAL);
51}
52
53static void
54test_create_close(int fd)
55{
56 struct drm_i915_gem_create create;
57 struct drm_gem_close close;
58 int ret;
59
60 printf("Testing creating and closing an object.\n");
61
62 memset(&create, 0, sizeof(create));
63 create.size = 16 * 1024;
64 ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
65 assert(ret == 0);
66
67 close.handle = create.handle;
68 ret = ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close);
69}
70
71static void
72test_create_fd_close(int fd)
73{
74 struct drm_i915_gem_create create;
75 int ret;
76
77 printf("Testing closing with an object allocated.\n");
78
79 memset(&create, 0, sizeof(create));
80 create.size = 16 * 1024;
81 ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
82 assert(ret == 0);
83
84 close(fd);
85}
86
87int main(int argc, char **argv)
88{
89 int fd;
90
91 fd = drm_open_matching("8086:*", 0);
92 if (fd < 0) {
93 fprintf(stderr, "failed to open intel drm device\n");
94 return 0;
95 }
96
97 test_bad_close(fd);
98 test_create_close(fd);
99 test_create_fd_close(fd);
100
101 return 0;
102}
diff --git a/tests/gem_flink.c b/tests/gem_flink.c
deleted file mode 100644
index ce43e422..00000000
--- a/tests/gem_flink.c
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 * Copyright © 2008 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <assert.h>
32#include <fcntl.h>
33#include <inttypes.h>
34#include <errno.h>
35#include <sys/stat.h>
36#include "drm.h"
37#include "i915_drm.h"
38
39static void
40test_flink(int fd)
41{
42 struct drm_i915_gem_create create;
43 struct drm_gem_flink flink;
44 struct drm_gem_open open;
45 int ret;
46
47 printf("Testing flink and open.\n");
48
49 memset(&create, 0, sizeof(create));
50 create.size = 16 * 1024;
51 ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
52 assert(ret == 0);
53
54 flink.handle = create.handle;
55 ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
56 assert(ret == 0);
57
58 open.name = flink.name;
59 ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open);
60 assert(ret == 0);
61 assert(open.handle != 0);
62}
63
64static void
65test_double_flink(int fd)
66{
67 struct drm_i915_gem_create create;
68 struct drm_gem_flink flink;
69 struct drm_gem_flink flink2;
70 int ret;
71
72 printf("Testing repeated flink.\n");
73
74 memset(&create, 0, sizeof(create));
75 create.size = 16 * 1024;
76 ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
77 assert(ret == 0);
78
79 flink.handle = create.handle;
80 ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
81 assert(ret == 0);
82
83 flink2.handle = create.handle;
84 ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink2);
85 assert(ret == 0);
86 assert(flink2.name == flink.name);
87}
88
89static void
90test_bad_flink(int fd)
91{
92 struct drm_gem_flink flink;
93 int ret;
94
95 printf("Testing error return on bad flink ioctl.\n");
96
97 flink.handle = 0x10101010;
98 ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
99 assert(ret == -1 && errno == ENOENT);
100}
101
102static void
103test_bad_open(int fd)
104{
105 struct drm_gem_open open;
106 int ret;
107
108 printf("Testing error return on bad open ioctl.\n");
109
110 open.name = 0x10101010;
111 ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &open);
112
113 assert(ret == -1 && errno == ENOENT);
114}
115
116int main(int argc, char **argv)
117{
118 int fd;
119
120 if (geteuid()) {
121 fprintf(stderr, "requires root privileges, skipping\n");
122 return 77;
123 }
124
125 fd = drm_open_matching("8086:*", 0);
126 if (fd < 0) {
127 fprintf(stderr, "failed to open intel drm device, skipping\n");
128 return 77;
129 }
130
131 test_flink(fd);
132 test_double_flink(fd);
133 test_bad_flink(fd);
134 test_bad_open(fd);
135
136 return 0;
137}
diff --git a/tests/gem_mmap.c b/tests/gem_mmap.c
deleted file mode 100644
index 2239789f..00000000
--- a/tests/gem_mmap.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/*
2 * Copyright © 2008 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <assert.h>
32#include <fcntl.h>
33#include <inttypes.h>
34#include <errno.h>
35#include <sys/stat.h>
36#include "drm.h"
37#include "i915_drm.h"
38
39#define OBJECT_SIZE 16384
40
41int do_read(int fd, int handle, void *buf, int offset, int size)
42{
43 struct drm_i915_gem_pread read;
44
45 /* Ensure that we don't have any convenient data in buf in case
46 * we fail.
47 */
48 memset(buf, 0xd0, size);
49
50 memset(&read, 0, sizeof(read));
51 read.handle = handle;
52 read.data_ptr = (uintptr_t)buf;
53 read.size = size;
54 read.offset = offset;
55
56 return ioctl(fd, DRM_IOCTL_I915_GEM_PREAD, &read);
57}
58
59int do_write(int fd, int handle, void *buf, int offset, int size)
60{
61 struct drm_i915_gem_pwrite write;
62
63 memset(&write, 0, sizeof(write));
64 write.handle = handle;
65 write.data_ptr = (uintptr_t)buf;
66 write.size = size;
67 write.offset = offset;
68
69 return ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &write);
70}
71
72int main(int argc, char **argv)
73{
74 int fd;
75 struct drm_i915_gem_create create;
76 struct drm_i915_gem_mmap mmap;
77 struct drm_gem_close unref;
78 uint8_t expected[OBJECT_SIZE];
79 uint8_t buf[OBJECT_SIZE];
80 uint8_t *addr;
81 int ret;
82 int handle;
83
84 fd = drm_open_matching("8086:*", 0);
85 if (fd < 0) {
86 fprintf(stderr, "failed to open intel drm device, skipping\n");
87 return 0;
88 }
89
90 memset(&mmap, 0, sizeof(mmap));
91 mmap.handle = 0x10101010;
92 mmap.offset = 0;
93 mmap.size = 4096;
94 printf("Testing mmaping of bad object.\n");
95 ret = ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, &mmap);
96 assert(ret == -1 && errno == ENOENT);
97
98 memset(&create, 0, sizeof(create));
99 create.size = OBJECT_SIZE;
100 ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
101 assert(ret == 0);
102 handle = create.handle;
103
104 printf("Testing mmaping of newly created object.\n");
105 mmap.handle = handle;
106 mmap.offset = 0;
107 mmap.size = OBJECT_SIZE;
108 ret = ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, &mmap);
109 assert(ret == 0);
110 addr = (uint8_t *)(uintptr_t)mmap.addr_ptr;
111
112 printf("Testing contents of newly created object.\n");
113 memset(expected, 0, sizeof(expected));
114 assert(memcmp(addr, expected, sizeof(expected)) == 0);
115
116 printf("Testing coherency of writes and mmap reads.\n");
117 memset(buf, 0, sizeof(buf));
118 memset(buf + 1024, 0x01, 1024);
119 memset(expected + 1024, 0x01, 1024);
120 ret = do_write(fd, handle, buf, 0, OBJECT_SIZE);
121 assert(ret == 0);
122 assert(memcmp(buf, addr, sizeof(buf)) == 0);
123
124 printf("Testing that mapping stays after close\n");
125 unref.handle = handle;
126 ret = ioctl(fd, DRM_IOCTL_GEM_CLOSE, &unref);
127 assert(ret == 0);
128 assert(memcmp(buf, addr, sizeof(buf)) == 0);
129
130 printf("Testing unmapping\n");
131 munmap(addr, OBJECT_SIZE);
132
133 close(fd);
134
135 return 0;
136}
diff --git a/tests/gem_readwrite.c b/tests/gem_readwrite.c
deleted file mode 100644
index 07dc853a..00000000
--- a/tests/gem_readwrite.c
+++ /dev/null
@@ -1,139 +0,0 @@
1/*
2 * Copyright © 2008 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <assert.h>
32#include <fcntl.h>
33#include <inttypes.h>
34#include <errno.h>
35#include <sys/stat.h>
36#include "drm.h"
37#include "i915_drm.h"
38
39#define OBJECT_SIZE 16384
40
41int do_read(int fd, int handle, void *buf, int offset, int size)
42{
43 struct drm_i915_gem_pread read;
44
45 /* Ensure that we don't have any convenient data in buf in case
46 * we fail.
47 */
48 memset(buf, 0xd0, size);
49
50 memset(&read, 0, sizeof(read));
51 read.handle = handle;
52 read.data_ptr = (uintptr_t)buf;
53 read.size = size;
54 read.offset = offset;
55
56 return ioctl(fd, DRM_IOCTL_I915_GEM_PREAD, &read);
57}
58
59int do_write(int fd, int handle, void *buf, int offset, int size)
60{
61 struct drm_i915_gem_pwrite write;
62
63 memset(&write, 0, sizeof(write));
64 write.handle = handle;
65 write.data_ptr = (uintptr_t)buf;
66 write.size = size;
67 write.offset = offset;
68
69 return ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &write);
70}
71
72int main(int argc, char **argv)
73{
74 int fd;
75 struct drm_i915_gem_create create;
76 uint8_t expected[OBJECT_SIZE];
77 uint8_t buf[OBJECT_SIZE];
78 int ret;
79 int handle;
80
81 fd = drm_open_matching("8086:*", 0);
82 if (fd < 0) {
83 fprintf(stderr, "failed to open intel drm device, skipping\n");
84 return 0;
85 }
86
87 memset(&create, 0, sizeof(create));
88 create.size = OBJECT_SIZE;
89 ret = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
90 assert(ret == 0);
91 handle = create.handle;
92
93 printf("Testing contents of newly created object.\n");
94 ret = do_read(fd, handle, buf, 0, OBJECT_SIZE);
95 assert(ret == 0);
96 memset(&expected, 0, sizeof(expected));
97 assert(memcmp(expected, buf, sizeof(expected)) == 0);
98
99 printf("Testing read beyond end of buffer.\n");
100 ret = do_read(fd, handle, buf, OBJECT_SIZE / 2, OBJECT_SIZE);
101 printf("%d %d\n", ret, errno);
102 assert(ret == -1 && errno == EINVAL);
103
104 printf("Testing full write of buffer\n");
105 memset(buf, 0, sizeof(buf));
106 memset(buf + 1024, 0x01, 1024);
107 memset(expected + 1024, 0x01, 1024);
108 ret = do_write(fd, handle, buf, 0, OBJECT_SIZE);
109 assert(ret == 0);
110 ret = do_read(fd, handle, buf, 0, OBJECT_SIZE);
111 assert(ret == 0);
112 assert(memcmp(buf, expected, sizeof(buf)) == 0);
113
114 printf("Testing partial write of buffer\n");
115 memset(buf + 4096, 0x02, 1024);
116 memset(expected + 4096, 0x02, 1024);
117 ret = do_write(fd, handle, buf + 4096, 4096, 1024);
118 assert(ret == 0);
119 ret = do_read(fd, handle, buf, 0, OBJECT_SIZE);
120 assert(ret == 0);
121 assert(memcmp(buf, expected, sizeof(buf)) == 0);
122
123 printf("Testing partial read of buffer\n");
124 ret = do_read(fd, handle, buf, 512, 1024);
125 assert(ret == 0);
126 assert(memcmp(buf, expected + 512, 1024) == 0);
127
128 printf("Testing read of bad buffer handle\n");
129 ret = do_read(fd, 1234, buf, 0, 1024);
130 assert(ret == -1 && errno == ENOENT);
131
132 printf("Testing write of bad buffer handle\n");
133 ret = do_write(fd, 1234, buf, 0, 1024);
134 assert(ret == -1 && errno == ENOENT);
135
136 close(fd);
137
138 return 0;
139}
diff --git a/tests/getclient.c b/tests/getclient.c
index 349c16ec..481ce119 100644
--- a/tests/getclient.c
+++ b/tests/getclient.c
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28#include <limits.h> 28#include <limits.h>
29#include <sys/ioctl.h>
29#include "drmtest.h" 30#include "drmtest.h"
30 31
31/** 32/**
diff --git a/tests/getstats.c b/tests/getstats.c
index bd55b12e..8a7d2999 100644
--- a/tests/getstats.c
+++ b/tests/getstats.c
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28#include <limits.h> 28#include <limits.h>
29#include <sys/ioctl.h>
29#include "drmtest.h" 30#include "drmtest.h"
30 31
31/** 32/**
@@ -44,8 +45,6 @@ int main(int argc, char **argv)
44 ret = ioctl(fd, DRM_IOCTL_GET_STATS, &stats); 45 ret = ioctl(fd, DRM_IOCTL_GET_STATS, &stats);
45 assert(ret == 0); 46 assert(ret == 0);
46 47
47 assert(stats.count >= 0);
48
49 close(fd); 48 close(fd);
50 return 0; 49 return 0;
51} 50}
diff --git a/tests/hash.c b/tests/hash.c
new file mode 100644
index 00000000..4475fba9
--- /dev/null
+++ b/tests/hash.c
@@ -0,0 +1,217 @@
1/* xf86drmHash.c -- Small hash table support for integer -> integer mapping
2 * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
27 *
28 * DESCRIPTION
29 *
30 * This file contains a straightforward implementation of a fixed-sized
31 * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for
32 * collision resolution. There are two potentially interesting things
33 * about this implementation:
34 *
35 * 1) The table is power-of-two sized. Prime sized tables are more
36 * traditional, but do not have a significant advantage over power-of-two
37 * sized table, especially when double hashing is not used for collision
38 * resolution.
39 *
40 * 2) The hash computation uses a table of random integers [Hanson97,
41 * pp. 39-41].
42 *
43 * FUTURE ENHANCEMENTS
44 *
45 * With a table size of 512, the current implementation is sufficient for a
46 * few hundred keys. Since this is well above the expected size of the
47 * tables for which this implementation was designed, the implementation of
48 * dynamic hash tables was postponed until the need arises. A common (and
49 * naive) approach to dynamic hash table implementation simply creates a
50 * new hash table when necessary, rehashes all the data into the new table,
51 * and destroys the old table. The approach in [Larson88] is superior in
52 * two ways: 1) only a portion of the table is expanded when needed,
53 * distributing the expansion cost over several insertions, and 2) portions
54 * of the table can be locked, enabling a scalable thread-safe
55 * implementation.
56 *
57 * REFERENCES
58 *
59 * [Hanson97] David R. Hanson. C Interfaces and Implementations:
60 * Techniques for Creating Reusable Software. Reading, Massachusetts:
61 * Addison-Wesley, 1997.
62 *
63 * [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3:
64 * Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973.
65 *
66 * [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April
67 * 1988, pp. 446-457.
68 *
69 */
70
71#include <stdio.h>
72#include <stdlib.h>
73
74#include "xf86drm.h"
75#include "xf86drmHash.h"
76
77#define DIST_LIMIT 10
78static int dist[DIST_LIMIT];
79
80static void clear_dist(void) {
81 int i;
82
83 for (i = 0; i < DIST_LIMIT; i++)
84 dist[i] = 0;
85}
86
87static int count_entries(HashBucketPtr bucket)
88{
89 int count = 0;
90
91 for (; bucket; bucket = bucket->next)
92 ++count;
93 return count;
94}
95
96static void update_dist(int count)
97{
98 if (count >= DIST_LIMIT)
99 ++dist[DIST_LIMIT-1];
100 else
101 ++dist[count];
102}
103
104static void compute_dist(HashTablePtr table)
105{
106 int i;
107 HashBucketPtr bucket;
108
109 printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
110 table->entries, table->hits, table->partials, table->misses);
111 clear_dist();
112 for (i = 0; i < HASH_SIZE; i++) {
113 bucket = table->buckets[i];
114 update_dist(count_entries(bucket));
115 }
116 for (i = 0; i < DIST_LIMIT; i++) {
117 if (i != DIST_LIMIT-1)
118 printf("%5d %10d\n", i, dist[i]);
119 else
120 printf("other %10d\n", dist[i]);
121 }
122}
123
124static int check_table(HashTablePtr table,
125 unsigned long key, void * value)
126{
127 void *retval;
128 int retcode = drmHashLookup(table, key, &retval);
129
130 switch (retcode) {
131 case -1:
132 printf("Bad magic = 0x%08lx:"
133 " key = %lu, expected = %p, returned = %p\n",
134 table->magic, key, value, retval);
135 break;
136 case 1:
137 printf("Not found: key = %lu, expected = %p, returned = %p\n",
138 key, value, retval);
139 break;
140 case 0:
141 if (value != retval) {
142 printf("Bad value: key = %lu, expected = %p, returned = %p\n",
143 key, value, retval);
144 retcode = -1;
145 }
146 break;
147 default:
148 printf("Bad retcode = %d: key = %lu, expected = %p, returned = %p\n",
149 retcode, key, value, retval);
150 break;
151 }
152 return retcode;
153}
154
155int main(void)
156{
157 HashTablePtr table;
158 unsigned long i;
159 int ret = 0;
160
161 printf("\n***** 256 consecutive integers ****\n");
162 table = drmHashCreate();
163 for (i = 0; i < 256; i++)
164 drmHashInsert(table, i, (void *)(i << 16 | i));
165 for (i = 0; i < 256; i++)
166 ret |= check_table(table, i, (void *)(i << 16 | i));
167 compute_dist(table);
168 drmHashDestroy(table);
169
170 printf("\n***** 1024 consecutive integers ****\n");
171 table = drmHashCreate();
172 for (i = 0; i < 1024; i++)
173 drmHashInsert(table, i, (void *)(i << 16 | i));
174 for (i = 0; i < 1024; i++)
175 ret |= check_table(table, i, (void *)(i << 16 | i));
176 compute_dist(table);
177 drmHashDestroy(table);
178
179 printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
180 table = drmHashCreate();
181 for (i = 0; i < 1024; i++)
182 drmHashInsert(table, i*4096, (void *)(i << 16 | i));
183 for (i = 0; i < 1024; i++)
184 ret |= check_table(table, i*4096, (void *)(i << 16 | i));
185 compute_dist(table);
186 drmHashDestroy(table);
187
188 printf("\n***** 1024 random integers ****\n");
189 table = drmHashCreate();
190 srandom(0xbeefbeef);
191 for (i = 0; i < 1024; i++)
192 drmHashInsert(table, random(), (void *)(i << 16 | i));
193 srandom(0xbeefbeef);
194 for (i = 0; i < 1024; i++)
195 ret |= check_table(table, random(), (void *)(i << 16 | i));
196 srandom(0xbeefbeef);
197 for (i = 0; i < 1024; i++)
198 ret |= check_table(table, random(), (void *)(i << 16 | i));
199 compute_dist(table);
200 drmHashDestroy(table);
201
202 printf("\n***** 5000 random integers ****\n");
203 table = drmHashCreate();
204 srandom(0xbeefbeef);
205 for (i = 0; i < 5000; i++)
206 drmHashInsert(table, random(), (void *)(i << 16 | i));
207 srandom(0xbeefbeef);
208 for (i = 0; i < 5000; i++)
209 ret |= check_table(table, random(), (void *)(i << 16 | i));
210 srandom(0xbeefbeef);
211 for (i = 0; i < 5000; i++)
212 ret |= check_table(table, random(), (void *)(i << 16 | i));
213 compute_dist(table);
214 drmHashDestroy(table);
215
216 return ret;
217}
diff --git a/tests/kms/Makefile.am b/tests/kms/Makefile.am
new file mode 100644
index 00000000..6645af7a
--- /dev/null
+++ b/tests/kms/Makefile.am
@@ -0,0 +1,36 @@
1AM_CPPFLAGS = \
2 -I$(top_srcdir)/include/drm \
3 -I$(top_srcdir)/tests \
4 -I$(top_srcdir)
5
6AM_CFLAGS = \
7 $(WARN_CFLAGS)
8
9noinst_LTLIBRARIES = libkms-test.la
10
11libkms_test_la_SOURCES = \
12 libkms-test.h \
13 libkms-test-crtc.c \
14 libkms-test-device.c \
15 libkms-test-framebuffer.c \
16 libkms-test-plane.c \
17 libkms-test-screen.c
18
19libkms_test_la_LIBADD = \
20 $(top_builddir)/libdrm.la
21
22if HAVE_INSTALL_TESTS
23bin_PROGRAMS = \
24 kms-steal-crtc \
25 kms-universal-planes
26else
27noinst_PROGRAMS = \
28 kms-steal-crtc \
29 kms-universal-planes
30endif
31
32kms_steal_crtc_SOURCES = kms-steal-crtc.c
33kms_steal_crtc_LDADD = libkms-test.la ../util/libutil.la $(CAIRO_LIBS)
34
35kms_universal_planes_SOURCES = kms-universal-planes.c
36kms_universal_planes_LDADD = libkms-test.la $(CAIRO_LIBS)
diff --git a/tests/kms/kms-steal-crtc.c b/tests/kms/kms-steal-crtc.c
new file mode 100644
index 00000000..2f7f327e
--- /dev/null
+++ b/tests/kms/kms-steal-crtc.c
@@ -0,0 +1,161 @@
1/*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <errno.h>
29#include <fcntl.h>
30#include <signal.h>
31#include <stdio.h>
32#include <string.h>
33#include <unistd.h>
34
35#include <drm_fourcc.h>
36
37#include "util/pattern.h"
38#include "libkms-test.h"
39
40static void signal_handler(int signum)
41{
42}
43
44int main(int argc, char *argv[])
45{
46 struct kms_framebuffer *fb;
47 struct kms_screen *screen;
48 struct kms_device *device;
49 unsigned int index = 0;
50 struct sigaction sa;
51 int fd, err;
52 void *ptr;
53
54 if (argc < 2) {
55 fprintf(stderr, "usage: %s DEVICE\n", argv[0]);
56 return 1;
57 }
58
59 memset(&sa, 0, sizeof(sa));
60 sa.sa_handler = signal_handler;
61
62 err = sigaction(SIGINT, &sa, NULL);
63 if (err < 0) {
64 fprintf(stderr, "sigaction() failed: %m\n");
65 return 1;
66 }
67
68 fd = open(argv[1], O_RDWR);
69 if (fd < 0) {
70 fprintf(stderr, "open() failed: %m\n");
71 return 1;
72 }
73
74 device = kms_device_open(fd);
75 if (!device) {
76 fprintf(stderr, "kms_device_open() failed: %m\n");
77 return 1;
78 }
79
80 if (device->num_screens < 1) {
81 fprintf(stderr, "no screens found\n");
82 kms_device_close(device);
83 close(fd);
84 return 1;
85 }
86
87 /* TODO: allow command-line to override */
88 screen = device->screens[0];
89
90 printf("Using screen %s, resolution %ux%u\n", screen->name,
91 screen->width, screen->height);
92
93 fb = kms_framebuffer_create(device, screen->width, screen->height,
94 DRM_FORMAT_XRGB8888);
95 if (!fb) {
96 fprintf(stderr, "kms_framebuffer_create() failed\n");
97 return 1;
98 }
99
100 err = kms_framebuffer_map(fb, &ptr);
101 if (err < 0) {
102 fprintf(stderr, "kms_framebuffer_map() failed: %d\n", err);
103 return 1;
104 }
105
106 util_fill_pattern(fb->format, UTIL_PATTERN_SMPTE, &ptr, fb->width,
107 fb->height, fb->pitch);
108
109 kms_framebuffer_unmap(fb);
110
111 err = kms_screen_set(screen, device->crtcs[index++], fb);
112 if (err < 0) {
113 fprintf(stderr, "kms_screen_set() failed: %d\n", err);
114 return 1;
115 }
116
117 while (true) {
118 int nfds = STDIN_FILENO + 1;
119 struct timeval timeout;
120 fd_set fds;
121
122 memset(&timeout, 0, sizeof(timeout));
123 timeout.tv_sec = 5;
124 timeout.tv_usec = 0;
125
126 FD_ZERO(&fds);
127 FD_SET(STDIN_FILENO, &fds);
128
129 err = select(nfds, &fds, NULL, NULL, &timeout);
130 if (err < 0) {
131 if (errno == EINTR)
132 break;
133
134 fprintf(stderr, "select() failed: %d\n", errno);
135 break;
136 }
137
138 if (err > 0) {
139 if (FD_ISSET(STDIN_FILENO, &fds))
140 break;
141 }
142
143 /* switch CRTC */
144 if (index >= device->num_crtcs)
145 index = 0;
146
147 err = kms_screen_set(screen, device->crtcs[index], fb);
148 if (err < 0) {
149 fprintf(stderr, "kms_screen_set() failed: %d\n", err);
150 break;
151 }
152
153 index++;
154 }
155
156 kms_framebuffer_free(fb);
157 kms_device_close(device);
158 close(fd);
159
160 return 0;
161}
diff --git a/tests/kms/kms-universal-planes.c b/tests/kms/kms-universal-planes.c
new file mode 100644
index 00000000..9151231f
--- /dev/null
+++ b/tests/kms/kms-universal-planes.c
@@ -0,0 +1,358 @@
1/*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <fcntl.h>
29#include <getopt.h>
30#include <stdbool.h>
31#include <stdint.h>
32#include <stdio.h>
33#include <string.h>
34#include <unistd.h>
35
36#include <drm_fourcc.h>
37#include "xf86drm.h"
38
39#include "util/common.h"
40#include "libkms-test.h"
41
42static const uint32_t formats[] = {
43 DRM_FORMAT_XRGB8888,
44 DRM_FORMAT_XBGR8888,
45 DRM_FORMAT_RGBA8888,
46};
47
48static uint32_t choose_format(struct kms_plane *plane)
49{
50 unsigned int i;
51
52 for (i = 0; i < ARRAY_SIZE(formats); i++)
53 if (kms_plane_supports_format(plane, formats[i]))
54 return formats[i];
55
56 return 0;
57}
58
59static void prepare_framebuffer(struct kms_framebuffer *fb, bool invert)
60{
61 const unsigned int block_size = 16;
62 uint32_t colors[2];
63 unsigned int i, j;
64 uint32_t *buf;
65 void *ptr;
66 int err;
67
68 switch (fb->format) {
69 case DRM_FORMAT_XRGB8888:
70 printf("using XRGB8888 format\n");
71 /* XXRRGGBB */
72 colors[0] = 0xffff0000;
73 colors[1] = 0xff0000ff;
74 break;
75
76 case DRM_FORMAT_XBGR8888:
77 printf("using XBGR8888 format\n");
78 /* XXBBGGRR */
79 colors[0] = 0xff0000ff;
80 colors[1] = 0xffff0000;
81 break;
82
83 case DRM_FORMAT_RGBA8888:
84 printf("using RGBA8888 format\n");
85 /* RRGGBBAA */
86 colors[0] = 0xff0000ff;
87 colors[1] = 0x0000ffff;
88 break;
89
90 default:
91 colors[0] = 0xffffffff;
92 colors[1] = 0xffffffff;
93 break;
94 }
95
96 err = kms_framebuffer_map(fb, &ptr);
97 if (err < 0) {
98 fprintf(stderr, "kms_framebuffer_map() failed: %s\n",
99 strerror(-err));
100 return;
101 }
102
103 buf = ptr;
104
105 for (j = 0; j < fb->height; j++) {
106 for (i = 0; i < fb->width; i++) {
107 unsigned int color = (j / block_size) ^
108 (i / block_size);
109
110 if (invert)
111 color ^= color;
112
113 *buf++ = colors[color & 1];
114 }
115 }
116
117 kms_framebuffer_unmap(fb);
118}
119
120int main(int argc, char *argv[])
121{
122 static const char opts[] = "chopv";
123 static struct option options[] = {
124 { "cursor", 0, 0, 'c' },
125 { "help", 0, 0, 'h' },
126 { "overlay", 0, 0, 'o' },
127 { "primary", 0, 0, 'p' },
128 { "verbose", 0, 0, 'v' },
129 { 0, 0, 0, 0 },
130 };
131 struct kms_framebuffer *cursor = NULL;
132 struct kms_framebuffer *root = NULL;
133 struct kms_framebuffer *fb = NULL;
134 struct kms_device *device;
135 bool use_overlay = false;
136 bool use_primary = false;
137 struct kms_plane *plane;
138 bool use_cursor = false;
139 bool verbose = false;
140 unsigned int i;
141 int opt, idx;
142 int fd, err;
143
144 while ((opt = getopt_long(argc, argv, opts, options, &idx)) != -1) {
145 switch (opt) {
146 case 'c':
147 use_cursor = true;
148 break;
149
150 case 'h':
151 break;
152
153 case 'o':
154 use_overlay = true;
155 break;
156
157 case 'p':
158 use_primary = true;
159 break;
160
161 case 'v':
162 verbose = true;
163 break;
164
165 default:
166 printf("unknown option \"%c\"\n", opt);
167 return 1;
168 }
169 }
170
171 if (optind >= argc) {
172 fprintf(stderr, "usage: %s [options] DEVICE\n", argv[0]);
173 return 1;
174 }
175
176 fd = open(argv[optind], O_RDWR);
177 if (fd < 0) {
178 fprintf(stderr, "open() failed: %m\n");
179 return 1;
180 }
181
182 err = drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
183 if (err < 0) {
184 fprintf(stderr, "drmSetClientCap() failed: %d\n", err);
185 return 1;
186 }
187
188 device = kms_device_open(fd);
189 if (!device)
190 return 1;
191
192 if (verbose) {
193 printf("Screens: %u\n", device->num_screens);
194
195 for (i = 0; i < device->num_screens; i++) {
196 struct kms_screen *screen = device->screens[i];
197 const char *status = "disconnected";
198
199 if (screen->connected)
200 status = "connected";
201
202 printf(" %u: %x\n", i, screen->id);
203 printf(" Status: %s\n", status);
204 printf(" Name: %s\n", screen->name);
205 printf(" Resolution: %ux%u\n", screen->width,
206 screen->height);
207 }
208
209 printf("Planes: %u\n", device->num_planes);
210
211 for (i = 0; i < device->num_planes; i++) {
212 struct kms_plane *plane = device->planes[i];
213 const char *type = NULL;
214
215 switch (plane->type) {
216 case DRM_PLANE_TYPE_OVERLAY:
217 type = "overlay";
218 break;
219
220 case DRM_PLANE_TYPE_PRIMARY:
221 type = "primary";
222 break;
223
224 case DRM_PLANE_TYPE_CURSOR:
225 type = "cursor";
226 break;
227 }
228
229 printf(" %u: %p\n", i, plane);
230 printf(" ID: %x\n", plane->id);
231 printf(" CRTC: %x\n", plane->crtc->id);
232 printf(" Type: %x (%s)\n", plane->type, type);
233 }
234 }
235
236 if (use_cursor) {
237 unsigned int x, y;
238 uint32_t format;
239
240 plane = kms_device_find_plane_by_type(device,
241 DRM_PLANE_TYPE_CURSOR,
242 0);
243 if (!plane) {
244 fprintf(stderr, "no cursor plane found\n");
245 return 1;
246 }
247
248 format = choose_format(plane);
249 if (!format) {
250 fprintf(stderr, "no matching format found\n");
251 return 1;
252 }
253
254 cursor = kms_framebuffer_create(device, 32, 32, format);
255 if (!cursor) {
256 fprintf(stderr, "failed to create cursor buffer\n");
257 return 1;
258 }
259
260 prepare_framebuffer(cursor, false);
261
262 x = (device->screens[0]->width - cursor->width) / 2;
263 y = (device->screens[0]->height - cursor->height) / 2;
264
265 kms_plane_set(plane, cursor, x, y);
266 }
267
268 if (use_overlay) {
269 uint32_t format;
270
271 plane = kms_device_find_plane_by_type(device,
272 DRM_PLANE_TYPE_OVERLAY,
273 0);
274 if (!plane) {
275 fprintf(stderr, "no overlay plane found\n");
276 return 1;
277 }
278
279 format = choose_format(plane);
280 if (!format) {
281 fprintf(stderr, "no matching format found\n");
282 return 1;
283 }
284
285 fb = kms_framebuffer_create(device, 320, 240, format);
286 if (!fb)
287 return 1;
288
289 prepare_framebuffer(fb, false);
290
291 kms_plane_set(plane, fb, 0, 0);
292 }
293
294 if (use_primary) {
295 unsigned int x, y;
296 uint32_t format;
297
298 plane = kms_device_find_plane_by_type(device,
299 DRM_PLANE_TYPE_PRIMARY,
300 0);
301 if (!plane) {
302 fprintf(stderr, "no primary plane found\n");
303 return 1;
304 }
305
306 format = choose_format(plane);
307 if (!format) {
308 fprintf(stderr, "no matching format found\n");
309 return 1;
310 }
311
312 root = kms_framebuffer_create(device, 640, 480, format);
313 if (!root)
314 return 1;
315
316 prepare_framebuffer(root, true);
317
318 x = (device->screens[0]->width - root->width) / 2;
319 y = (device->screens[0]->height - root->height) / 2;
320
321 kms_plane_set(plane, root, x, y);
322 }
323
324 while (1) {
325 struct timeval timeout = { 1, 0 };
326 fd_set fds;
327
328 FD_ZERO(&fds);
329 FD_SET(STDIN_FILENO, &fds);
330
331 err = select(STDIN_FILENO + 1, &fds, NULL, NULL, &timeout);
332 if (err < 0) {
333 fprintf(stderr, "select() failed: %m\n");
334 break;
335 }
336
337 /* timeout */
338 if (err == 0)
339 continue;
340
341 if (FD_ISSET(STDIN_FILENO, &fds))
342 break;
343 }
344
345 if (cursor)
346 kms_framebuffer_free(cursor);
347
348 if (root)
349 kms_framebuffer_free(root);
350
351 if (fb)
352 kms_framebuffer_free(fb);
353
354 kms_device_close(device);
355 close(fd);
356
357 return 0;
358}
diff --git a/tests/kms/libkms-test-crtc.c b/tests/kms/libkms-test-crtc.c
new file mode 100644
index 00000000..3adb4903
--- /dev/null
+++ b/tests/kms/libkms-test-crtc.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "libkms-test.h"
29
30struct kms_crtc *kms_crtc_create(struct kms_device *device, uint32_t id)
31{
32 struct kms_crtc *crtc;
33
34 crtc = calloc(1, sizeof(*crtc));
35 if (!crtc)
36 return NULL;
37
38 crtc->device = device;
39 crtc->id = id;
40
41 return crtc;
42}
43
44void kms_crtc_free(struct kms_crtc *crtc)
45{
46 free(crtc);
47}
diff --git a/tests/kms/libkms-test-device.c b/tests/kms/libkms-test-device.c
new file mode 100644
index 00000000..53c7349b
--- /dev/null
+++ b/tests/kms/libkms-test-device.c
@@ -0,0 +1,218 @@
1/*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <stdio.h>
29#include <string.h>
30#include <unistd.h>
31
32#include "util/common.h"
33#include "libkms-test.h"
34
35static const char *const connector_names[] = {
36 "Unknown",
37 "VGA",
38 "DVI-I",
39 "DVI-D",
40 "DVI-A",
41 "Composite",
42 "SVIDEO",
43 "LVDS",
44 "Component",
45 "9PinDIN",
46 "DisplayPort",
47 "HDMI-A",
48 "HDMI-B",
49 "TV",
50 "eDP",
51 "Virtual",
52 "DSI",
53};
54
55static void kms_device_probe_screens(struct kms_device *device)
56{
57 unsigned int counts[ARRAY_SIZE(connector_names)];
58 struct kms_screen *screen;
59 drmModeRes *res;
60 int i;
61
62 memset(counts, 0, sizeof(counts));
63
64 res = drmModeGetResources(device->fd);
65 if (!res)
66 return;
67
68 device->screens = calloc(res->count_connectors, sizeof(screen));
69 if (!device->screens)
70 return;
71
72 for (i = 0; i < res->count_connectors; i++) {
73 unsigned int *count;
74 const char *type;
75 int len;
76
77 screen = kms_screen_create(device, res->connectors[i]);
78 if (!screen)
79 continue;
80
81 /* assign a unique name to this screen */
82 type = connector_names[screen->type];
83 count = &counts[screen->type];
84
85 len = snprintf(NULL, 0, "%s-%u", type, *count);
86
87 screen->name = malloc(len + 1);
88 if (!screen->name) {
89 free(screen);
90 continue;
91 }
92
93 snprintf(screen->name, len + 1, "%s-%u", type, *count);
94 (*count)++;
95
96 device->screens[i] = screen;
97 device->num_screens++;
98 }
99
100 drmModeFreeResources(res);
101}
102
103static void kms_device_probe_crtcs(struct kms_device *device)
104{
105 struct kms_crtc *crtc;
106 drmModeRes *res;
107 int i;
108
109 res = drmModeGetResources(device->fd);
110 if (!res)
111 return;
112
113 device->crtcs = calloc(res->count_crtcs, sizeof(crtc));
114 if (!device->crtcs)
115 return;
116
117 for (i = 0; i < res->count_crtcs; i++) {
118 crtc = kms_crtc_create(device, res->crtcs[i]);
119 if (!crtc)
120 continue;
121
122 device->crtcs[i] = crtc;
123 device->num_crtcs++;
124 }
125
126 drmModeFreeResources(res);
127}
128
129static void kms_device_probe_planes(struct kms_device *device)
130{
131 struct kms_plane *plane;
132 drmModePlaneRes *res;
133 unsigned int i;
134
135 res = drmModeGetPlaneResources(device->fd);
136 if (!res)
137 return;
138
139 device->planes = calloc(res->count_planes, sizeof(plane));
140 if (!device->planes)
141 return;
142
143 for (i = 0; i < res->count_planes; i++) {
144 plane = kms_plane_create(device, res->planes[i]);
145 if (!plane)
146 continue;
147
148 device->planes[i] = plane;
149 device->num_planes++;
150 }
151
152 drmModeFreePlaneResources(res);
153}
154
155static void kms_device_probe(struct kms_device *device)
156{
157 kms_device_probe_screens(device);
158 kms_device_probe_crtcs(device);
159 kms_device_probe_planes(device);
160}
161
162struct kms_device *kms_device_open(int fd)
163{
164 struct kms_device *device;
165
166 device = calloc(1, sizeof(*device));
167 if (!device)
168 return NULL;
169
170 device->fd = fd;
171
172 kms_device_probe(device);
173
174 return device;
175}
176
177void kms_device_close(struct kms_device *device)
178{
179 unsigned int i;
180
181 for (i = 0; i < device->num_planes; i++)
182 kms_plane_free(device->planes[i]);
183
184 free(device->planes);
185
186 for (i = 0; i < device->num_crtcs; i++)
187 kms_crtc_free(device->crtcs[i]);
188
189 free(device->crtcs);
190
191 for (i = 0; i < device->num_screens; i++)
192 kms_screen_free(device->screens[i]);
193
194 free(device->screens);
195
196 if (device->fd >= 0)
197 close(device->fd);
198
199 free(device);
200}
201
202struct kms_plane *kms_device_find_plane_by_type(struct kms_device *device,
203 uint32_t type,
204 unsigned int index)
205{
206 unsigned int i;
207
208 for (i = 0; i < device->num_planes; i++) {
209 if (device->planes[i]->type == type) {
210 if (index == 0)
211 return device->planes[i];
212
213 index--;
214 }
215 }
216
217 return NULL;
218}
diff --git a/tests/kms/libkms-test-framebuffer.c b/tests/kms/libkms-test-framebuffer.c
new file mode 100644
index 00000000..c9e5ad3c
--- /dev/null
+++ b/tests/kms/libkms-test-framebuffer.c
@@ -0,0 +1,157 @@
1/*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <errno.h>
29#include <string.h>
30
31#include <sys/mman.h>
32
33#include <drm_fourcc.h>
34
35#include "xf86drm.h"
36
37#include "libkms-test.h"
38
39struct kms_framebuffer *kms_framebuffer_create(struct kms_device *device,
40 unsigned int width,
41 unsigned int height,
42 uint32_t format)
43{
44 uint32_t handles[4], pitches[4], offsets[4];
45 struct drm_mode_create_dumb args;
46 struct kms_framebuffer *fb;
47 int err;
48
49 fb = calloc(1, sizeof(*fb));
50 if (!fb)
51 return NULL;
52
53 fb->device = device;
54 fb->width = width;
55 fb->height = height;
56 fb->format = format;
57
58 memset(&args, 0, sizeof(args));
59 args.width = width;
60 args.height = height;
61
62 switch (format) {
63 case DRM_FORMAT_XRGB8888:
64 case DRM_FORMAT_XBGR8888:
65 case DRM_FORMAT_RGBA8888:
66 args.bpp = 32;
67 break;
68
69 default:
70 free(fb);
71 return NULL;
72 }
73
74 err = drmIoctl(device->fd, DRM_IOCTL_MODE_CREATE_DUMB, &args);
75 if (err < 0) {
76 free(fb);
77 return NULL;
78 }
79
80 fb->handle = args.handle;
81 fb->pitch = args.pitch;
82 fb->size = args.size;
83
84 handles[0] = fb->handle;
85 pitches[0] = fb->pitch;
86 offsets[0] = 0;
87
88 err = drmModeAddFB2(device->fd, width, height, format, handles,
89 pitches, offsets, &fb->id, 0);
90 if (err < 0) {
91 kms_framebuffer_free(fb);
92 return NULL;
93 }
94
95 return fb;
96}
97
98void kms_framebuffer_free(struct kms_framebuffer *fb)
99{
100 struct kms_device *device = fb->device;
101 struct drm_mode_destroy_dumb args;
102 int err;
103
104 if (fb->id) {
105 err = drmModeRmFB(device->fd, fb->id);
106 if (err < 0) {
107 /* not much we can do now */
108 }
109 }
110
111 memset(&args, 0, sizeof(args));
112 args.handle = fb->handle;
113
114 err = drmIoctl(device->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &args);
115 if (err < 0) {
116 /* not much we can do now */
117 }
118
119 free(fb);
120}
121
122int kms_framebuffer_map(struct kms_framebuffer *fb, void **ptrp)
123{
124 struct kms_device *device = fb->device;
125 struct drm_mode_map_dumb args;
126 void *ptr;
127 int err;
128
129 if (fb->ptr) {
130 *ptrp = fb->ptr;
131 return 0;
132 }
133
134 memset(&args, 0, sizeof(args));
135 args.handle = fb->handle;
136
137 err = drmIoctl(device->fd, DRM_IOCTL_MODE_MAP_DUMB, &args);
138 if (err < 0)
139 return -errno;
140
141 ptr = mmap(0, fb->size, PROT_READ | PROT_WRITE, MAP_SHARED,
142 device->fd, args.offset);
143 if (ptr == MAP_FAILED)
144 return -errno;
145
146 *ptrp = fb->ptr = ptr;
147
148 return 0;
149}
150
151void kms_framebuffer_unmap(struct kms_framebuffer *fb)
152{
153 if (fb->ptr) {
154 munmap(fb->ptr, fb->size);
155 fb->ptr = NULL;
156 }
157}
diff --git a/tests/kms/libkms-test-plane.c b/tests/kms/libkms-test-plane.c
new file mode 100644
index 00000000..8eb78af1
--- /dev/null
+++ b/tests/kms/libkms-test-plane.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <errno.h>
29#include <string.h>
30
31#include "libkms-test.h"
32
33static int kms_plane_probe(struct kms_plane *plane)
34{
35 struct kms_device *device = plane->device;
36 drmModeObjectPropertiesPtr props;
37 drmModePlane *p;
38 unsigned int i;
39
40 p = drmModeGetPlane(device->fd, plane->id);
41 if (!p)
42 return -ENODEV;
43
44 /* TODO: allow dynamic assignment to CRTCs */
45 if (p->crtc_id == 0) {
46 for (i = 0; i < device->num_crtcs; i++) {
47 if (p->possible_crtcs & (1 << i)) {
48 p->crtc_id = device->crtcs[i]->id;
49 break;
50 }
51 }
52 }
53
54 for (i = 0; i < device->num_crtcs; i++) {
55 if (device->crtcs[i]->id == p->crtc_id) {
56 plane->crtc = device->crtcs[i];
57 break;
58 }
59 }
60
61 plane->formats = calloc(p->count_formats, sizeof(uint32_t));
62 if (!plane->formats)
63 return -ENOMEM;
64
65 for (i = 0; i < p->count_formats; i++)
66 plane->formats[i] = p->formats[i];
67
68 plane->num_formats = p->count_formats;
69
70 drmModeFreePlane(p);
71
72 props = drmModeObjectGetProperties(device->fd, plane->id,
73 DRM_MODE_OBJECT_PLANE);
74 if (!props)
75 return -ENODEV;
76
77 for (i = 0; i < props->count_props; i++) {
78 drmModePropertyPtr prop;
79
80 prop = drmModeGetProperty(device->fd, props->props[i]);
81 if (prop) {
82 if (strcmp(prop->name, "type") == 0)
83 plane->type = props->prop_values[i];
84
85 drmModeFreeProperty(prop);
86 }
87 }
88
89 drmModeFreeObjectProperties(props);
90
91 return 0;
92}
93
94struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id)
95{
96 struct kms_plane *plane;
97
98 plane = calloc(1, sizeof(*plane));
99 if (!plane)
100 return NULL;
101
102 plane->device = device;
103 plane->id = id;
104
105 kms_plane_probe(plane);
106
107 return plane;
108}
109
110void kms_plane_free(struct kms_plane *plane)
111{
112 free(plane);
113}
114
115int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb,
116 unsigned int x, unsigned int y)
117{
118 struct kms_device *device = plane->device;
119 int err;
120
121 err = drmModeSetPlane(device->fd, plane->id, plane->crtc->id, fb->id,
122 0, x, y, fb->width, fb->height, 0 << 16,
123 0 << 16, fb->width << 16, fb->height << 16);
124 if (err < 0)
125 return -errno;
126
127 return 0;
128}
129
130bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format)
131{
132 unsigned int i;
133
134 for (i = 0; i < plane->num_formats; i++)
135 if (plane->formats[i] == format)
136 return true;
137
138 return false;
139}
diff --git a/tests/kms/libkms-test-screen.c b/tests/kms/libkms-test-screen.c
new file mode 100644
index 00000000..33690222
--- /dev/null
+++ b/tests/kms/libkms-test-screen.c
@@ -0,0 +1,92 @@
1/*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <errno.h>
29#include <string.h>
30
31#include "libkms-test.h"
32
33static void kms_screen_probe(struct kms_screen *screen)
34{
35 struct kms_device *device = screen->device;
36 drmModeConnector *con;
37
38 con = drmModeGetConnector(device->fd, screen->id);
39 if (!con)
40 return;
41
42 screen->type = con->connector_type;
43
44 if (con->connection == DRM_MODE_CONNECTED)
45 screen->connected = true;
46 else
47 screen->connected = false;
48
49 memcpy(&screen->mode, &con->modes[0], sizeof(drmModeModeInfo));
50 screen->width = screen->mode.hdisplay;
51 screen->height = screen->mode.vdisplay;
52
53 drmModeFreeConnector(con);
54}
55
56struct kms_screen *kms_screen_create(struct kms_device *device, uint32_t id)
57{
58 struct kms_screen *screen;
59
60 screen = calloc(1, sizeof(*screen));
61 if (!screen)
62 return NULL;
63
64 screen->device = device;
65 screen->id = id;
66
67 kms_screen_probe(screen);
68
69 return screen;
70}
71
72void kms_screen_free(struct kms_screen *screen)
73{
74 if (screen)
75 free(screen->name);
76
77 free(screen);
78}
79
80int kms_screen_set(struct kms_screen *screen, struct kms_crtc *crtc,
81 struct kms_framebuffer *fb)
82{
83 struct kms_device *device = screen->device;
84 int err;
85
86 err = drmModeSetCrtc(device->fd, crtc->id, fb->id, 0, 0, &screen->id,
87 1, &screen->mode);
88 if (err < 0)
89 return -errno;
90
91 return 0;
92}
diff --git a/tests/kms/libkms-test.h b/tests/kms/libkms-test.h
new file mode 100644
index 00000000..7b1d02e9
--- /dev/null
+++ b/tests/kms/libkms-test.h
@@ -0,0 +1,120 @@
1/*
2 * Copyright © 2014 NVIDIA Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifndef LIBKMS_TEST_H
25#define LIBKMS_TEST_H
26
27#include <stdbool.h>
28#include <stdint.h>
29#include <stdlib.h>
30
31#include <xf86drmMode.h>
32
33struct kms_device {
34 int fd;
35
36 struct kms_screen **screens;
37 unsigned int num_screens;
38
39 struct kms_crtc **crtcs;
40 unsigned int num_crtcs;
41
42 struct kms_plane **planes;
43 unsigned int num_planes;
44};
45
46struct kms_device *kms_device_open(int fd);
47void kms_device_close(struct kms_device *device);
48
49struct kms_plane *kms_device_find_plane_by_type(struct kms_device *device,
50 uint32_t type,
51 unsigned int index);
52
53struct kms_crtc {
54 struct kms_device *device;
55 uint32_t id;
56};
57
58struct kms_crtc *kms_crtc_create(struct kms_device *device, uint32_t id);
59void kms_crtc_free(struct kms_crtc *crtc);
60
61struct kms_framebuffer {
62 struct kms_device *device;
63
64 unsigned int width;
65 unsigned int height;
66 unsigned int pitch;
67 uint32_t format;
68 size_t size;
69
70 uint32_t handle;
71 uint32_t id;
72
73 void *ptr;
74};
75
76struct kms_framebuffer *kms_framebuffer_create(struct kms_device *device,
77 unsigned int width,
78 unsigned int height,
79 uint32_t format);
80void kms_framebuffer_free(struct kms_framebuffer *fb);
81int kms_framebuffer_map(struct kms_framebuffer *fb, void **ptrp);
82void kms_framebuffer_unmap(struct kms_framebuffer *fb);
83
84struct kms_screen {
85 struct kms_device *device;
86 bool connected;
87 uint32_t type;
88 uint32_t id;
89
90 unsigned int width;
91 unsigned int height;
92 char *name;
93
94 drmModeModeInfo mode;
95};
96
97struct kms_screen *kms_screen_create(struct kms_device *device, uint32_t id);
98void kms_screen_free(struct kms_screen *screen);
99
100int kms_screen_set(struct kms_screen *screen, struct kms_crtc *crtc,
101 struct kms_framebuffer *fb);
102
103struct kms_plane {
104 struct kms_device *device;
105 struct kms_crtc *crtc;
106 unsigned int type;
107 uint32_t id;
108
109 uint32_t *formats;
110 unsigned int num_formats;
111};
112
113struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id);
114void kms_plane_free(struct kms_plane *plane);
115
116int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb,
117 unsigned int x, unsigned int y);
118bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format);
119
120#endif
diff --git a/tests/kmstest/Makefile.am b/tests/kmstest/Makefile.am
index 7903a267..fd21e612 100644
--- a/tests/kmstest/Makefile.am
+++ b/tests/kmstest/Makefile.am
@@ -1,4 +1,5 @@
1AM_CFLAGS = \ 1AM_CFLAGS = \
2 $(WARN_CFLAGS)\
2 -I$(top_srcdir)/include/drm \ 3 -I$(top_srcdir)/include/drm \
3 -I$(top_srcdir)/libkms/ \ 4 -I$(top_srcdir)/libkms/ \
4 -I$(top_srcdir) 5 -I$(top_srcdir)
diff --git a/tests/kmstest/main.c b/tests/kmstest/main.c
index 449d75f6..120bc0fa 100644
--- a/tests/kmstest/main.c
+++ b/tests/kmstest/main.c
@@ -37,7 +37,7 @@
37 return ret; \ 37 return ret; \
38 } 38 }
39 39
40int test_bo(struct kms_driver *kms) 40static int test_bo(struct kms_driver *kms)
41{ 41{
42 struct kms_bo *bo; 42 struct kms_bo *bo;
43 int ret; 43 int ret;
@@ -56,12 +56,16 @@ int test_bo(struct kms_driver *kms)
56 return 0; 56 return 0;
57} 57}
58 58
59char *drivers[] = { 59static const char *drivers[] = {
60 "i915", 60 "i915",
61 "radeon", 61 "radeon",
62 "nouveau", 62 "nouveau",
63 "vmwgfx", 63 "vmwgfx",
64 "exynos", 64 "exynos",
65 "amdgpu",
66 "imx-drm",
67 "rockchip",
68 "atmel-hlcdc",
65 NULL 69 NULL
66}; 70};
67 71
diff --git a/tests/lock.c b/tests/lock.c
index 86caa281..365681b5 100644
--- a/tests/lock.c
+++ b/tests/lock.c
@@ -30,6 +30,7 @@
30 */ 30 */
31 31
32#include <limits.h> 32#include <limits.h>
33#include <sys/ioctl.h>
33#include "drmtest.h" 34#include "drmtest.h"
34 35
35enum auth_event { 36enum auth_event {
diff --git a/tests/modeprint/Makefile.am b/tests/modeprint/Makefile.am
index 6420ef33..601dbc96 100644
--- a/tests/modeprint/Makefile.am
+++ b/tests/modeprint/Makefile.am
@@ -1,5 +1,7 @@
1AM_CFLAGS = \ 1AM_CFLAGS = \
2 $(WARN_CFLAGS)\
2 -I$(top_srcdir)/include/drm \ 3 -I$(top_srcdir)/include/drm \
4 -I$(top_srcdir)/tests \
3 -I$(top_srcdir) 5 -I$(top_srcdir)
4 6
5if HAVE_INSTALL_TESTS 7if HAVE_INSTALL_TESTS
diff --git a/tests/modeprint/modeprint.c b/tests/modeprint/modeprint.c
index 6f0d0390..0d854103 100644
--- a/tests/modeprint/modeprint.c
+++ b/tests/modeprint/modeprint.c
@@ -41,8 +41,9 @@
41#include "xf86drm.h" 41#include "xf86drm.h"
42#include "xf86drmMode.h" 42#include "xf86drmMode.h"
43 43
44#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 44#include "util/common.h"
45 45
46int current;
46int connectors; 47int connectors;
47int full_props; 48int full_props;
48int edid; 49int edid;
@@ -53,20 +54,21 @@ int crtcs;
53int fbs; 54int fbs;
54char *module_name; 55char *module_name;
55 56
56const char* getConnectionText(drmModeConnection conn) 57static const char* getConnectionText(drmModeConnection conn)
57{ 58{
58 switch (conn) { 59 switch (conn) {
59 case DRM_MODE_CONNECTED: 60 case DRM_MODE_CONNECTED:
60 return "connected"; 61 return "connected";
61 case DRM_MODE_DISCONNECTED: 62 case DRM_MODE_DISCONNECTED:
62 return "disconnected"; 63 return "disconnected";
64 case DRM_MODE_UNKNOWNCONNECTION:
63 default: 65 default:
64 return "unknown"; 66 return "unknown";
65 } 67 }
66 68
67} 69}
68 70
69int printMode(struct drm_mode_modeinfo *mode) 71static int printMode(struct drm_mode_modeinfo *mode)
70{ 72{
71 if (full_modes) { 73 if (full_modes) {
72 printf("Mode: %s\n", mode->name); 74 printf("Mode: %s\n", mode->name);
@@ -90,7 +92,7 @@ int printMode(struct drm_mode_modeinfo *mode)
90 return 0; 92 return 0;
91} 93}
92 94
93int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, uint64_t value) 95static int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, uint64_t value)
94{ 96{
95 const char *name = NULL; 97 const char *name = NULL;
96 int j; 98 int j;
@@ -123,9 +125,6 @@ int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, uint64_t
123 } 125 }
124 126
125 } else { 127 } else {
126 if (!strncmp(props->name, "DPMS", 4))
127 ;
128
129 for (j = 0; j < props->count_enums; j++) { 128 for (j = 0; j < props->count_enums; j++) {
130 printf("\t\t%lld = %s\n", props->enums[j].value, props->enums[j].name); 129 printf("\t\t%lld = %s\n", props->enums[j].value, props->enums[j].name);
131 if (props->enums[j].value == value) 130 if (props->enums[j].value == value)
@@ -161,7 +160,7 @@ static const char * const output_names[] = { "None",
161 "DSI", 160 "DSI",
162}; 161};
163 162
164int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uint32_t id) 163static int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uint32_t id)
165{ 164{
166 int i = 0; 165 int i = 0;
167 struct drm_mode_modeinfo *mode = NULL; 166 struct drm_mode_modeinfo *mode = NULL;
@@ -214,7 +213,7 @@ int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uin
214 return 0; 213 return 0;
215} 214}
216 215
217int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t id) 216static int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t id)
218{ 217{
219 printf("Encoder\n"); 218 printf("Encoder\n");
220 printf("\tid :%i\n", id); 219 printf("\tid :%i\n", id);
@@ -225,7 +224,7 @@ int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t
225 return 0; 224 return 0;
226} 225}
227 226
228int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id) 227static int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id)
229{ 228{
230 printf("Crtc\n"); 229 printf("Crtc\n");
231 printf("\tid : %i\n", id); 230 printf("\tid : %i\n", id);
@@ -239,7 +238,7 @@ int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id)
239 return 0; 238 return 0;
240} 239}
241 240
242int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb) 241static int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb)
243{ 242{
244 printf("Framebuffer\n"); 243 printf("Framebuffer\n");
245 printf("\thandle : %i\n", fb->handle); 244 printf("\thandle : %i\n", fb->handle);
@@ -253,7 +252,7 @@ int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb)
253 return 0; 252 return 0;
254} 253}
255 254
256int printRes(int fd, drmModeResPtr res) 255static int printRes(int fd, drmModeResPtr res)
257{ 256{
258 int i; 257 int i;
259 drmModeFBPtr fb; 258 drmModeFBPtr fb;
@@ -272,7 +271,7 @@ int printRes(int fd, drmModeResPtr res)
272 271
273 if (connectors) { 272 if (connectors) {
274 for (i = 0; i < res->count_connectors; i++) { 273 for (i = 0; i < res->count_connectors; i++) {
275 connector = drmModeGetConnector(fd, res->connectors[i]); 274 connector = (current ? drmModeGetConnectorCurrent : drmModeGetConnector) (fd, res->connectors[i]);
276 275
277 if (!connector) 276 if (!connector)
278 printf("Could not get connector %i\n", res->connectors[i]); 277 printf("Could not get connector %i\n", res->connectors[i]);
@@ -329,8 +328,9 @@ int printRes(int fd, drmModeResPtr res)
329 return 0; 328 return 0;
330} 329}
331 330
332void args(int argc, char **argv) 331static void args(int argc, char **argv)
333{ 332{
333 int defaults = 1;
334 int i; 334 int i;
335 335
336 fbs = 0; 336 fbs = 0;
@@ -341,32 +341,41 @@ void args(int argc, char **argv)
341 full_modes = 0; 341 full_modes = 0;
342 full_props = 0; 342 full_props = 0;
343 connectors = 0; 343 connectors = 0;
344 current = 0;
344 345
345 module_name = argv[1]; 346 module_name = argv[1];
346 347
347 for (i = 2; i < argc; i++) { 348 for (i = 2; i < argc; i++) {
348 if (strcmp(argv[i], "-fb") == 0) { 349 if (strcmp(argv[i], "-fb") == 0) {
349 fbs = 1; 350 fbs = 1;
351 defaults = 0;
350 } else if (strcmp(argv[i], "-crtcs") == 0) { 352 } else if (strcmp(argv[i], "-crtcs") == 0) {
351 crtcs = 1; 353 crtcs = 1;
354 defaults = 0;
352 } else if (strcmp(argv[i], "-cons") == 0) { 355 } else if (strcmp(argv[i], "-cons") == 0) {
353 connectors = 1; 356 connectors = 1;
354 modes = 1; 357 modes = 1;
358 defaults = 0;
355 } else if (strcmp(argv[i], "-modes") == 0) { 359 } else if (strcmp(argv[i], "-modes") == 0) {
356 connectors = 1; 360 connectors = 1;
357 modes = 1; 361 modes = 1;
362 defaults = 0;
358 } else if (strcmp(argv[i], "-full") == 0) { 363 } else if (strcmp(argv[i], "-full") == 0) {
359 connectors = 1; 364 connectors = 1;
360 modes = 1; 365 modes = 1;
361 full_modes = 1; 366 full_modes = 1;
367 defaults = 0;
362 } else if (strcmp(argv[i], "-props") == 0) { 368 } else if (strcmp(argv[i], "-props") == 0) {
363 connectors = 1; 369 connectors = 1;
364 full_props = 1; 370 full_props = 1;
371 defaults = 0;
365 } else if (strcmp(argv[i], "-edids") == 0) { 372 } else if (strcmp(argv[i], "-edids") == 0) {
366 connectors = 1; 373 connectors = 1;
367 edid = 1; 374 edid = 1;
375 defaults = 0;
368 } else if (strcmp(argv[i], "-encoders") == 0) { 376 } else if (strcmp(argv[i], "-encoders") == 0) {
369 encoders = 1; 377 encoders = 1;
378 defaults = 0;
370 } else if (strcmp(argv[i], "-v") == 0) { 379 } else if (strcmp(argv[i], "-v") == 0) {
371 fbs = 1; 380 fbs = 1;
372 edid = 1; 381 edid = 1;
@@ -376,10 +385,13 @@ void args(int argc, char **argv)
376 full_modes = 1; 385 full_modes = 1;
377 full_props = 1; 386 full_props = 1;
378 connectors = 1; 387 connectors = 1;
388 defaults = 0;
389 } else if (strcmp(argv[i], "-current") == 0) {
390 current = 1;
379 } 391 }
380 } 392 }
381 393
382 if (argc == 2) { 394 if (defaults) {
383 fbs = 1; 395 fbs = 1;
384 edid = 1; 396 edid = 1;
385 crtcs = 1; 397 crtcs = 1;
diff --git a/tests/modetest/Android.mk b/tests/modetest/Android.mk
index 6507b48b..ccdae6c8 100644
--- a/tests/modetest/Android.mk
+++ b/tests/modetest/Android.mk
@@ -8,5 +8,6 @@ LOCAL_SRC_FILES := $(filter-out %.h,$(MODETEST_FILES))
8LOCAL_MODULE := modetest 8LOCAL_MODULE := modetest
9 9
10LOCAL_SHARED_LIBRARIES := libdrm 10LOCAL_SHARED_LIBRARIES := libdrm
11LOCAL_STATIC_LIBRARIES := libdrm_util
11 12
12include $(BUILD_EXECUTABLE) 13include $(BUILD_EXECUTABLE)
diff --git a/tests/modetest/Makefile.am b/tests/modetest/Makefile.am
index 93820fac..25ce372f 100644
--- a/tests/modetest/Makefile.am
+++ b/tests/modetest/Makefile.am
@@ -4,6 +4,7 @@ AM_CFLAGS = $(filter-out -Wpointer-arith, $(WARN_CFLAGS))
4 4
5AM_CFLAGS += \ 5AM_CFLAGS += \
6 -I$(top_srcdir)/include/drm \ 6 -I$(top_srcdir)/include/drm \
7 -I$(top_srcdir)/tests \
7 -I$(top_srcdir) 8 -I$(top_srcdir)
8 9
9if HAVE_INSTALL_TESTS 10if HAVE_INSTALL_TESTS
@@ -18,11 +19,8 @@ modetest_SOURCES = $(MODETEST_FILES)
18 19
19modetest_LDADD = \ 20modetest_LDADD = \
20 $(top_builddir)/libdrm.la \ 21 $(top_builddir)/libdrm.la \
22 $(top_builddir)/tests/util/libutil.la \
23 $(CAIRO_LIBS) \
21 -lpthread 24 -lpthread
22 25
23if HAVE_CAIRO
24AM_CFLAGS += $(CAIRO_CFLAGS)
25modetest_LDADD += $(CAIRO_LIBS)
26endif
27
28EXTRA_DIST = Android.mk 26EXTRA_DIST = Android.mk
diff --git a/tests/modetest/buffers.c b/tests/modetest/buffers.c
index e4e81495..4fd310b9 100644
--- a/tests/modetest/buffers.c
+++ b/tests/modetest/buffers.c
@@ -39,18 +39,11 @@
39#include "drm.h" 39#include "drm.h"
40#include "drm_fourcc.h" 40#include "drm_fourcc.h"
41 41
42#include "libdrm.h" 42#include "libdrm_macros.h"
43#include "xf86drm.h" 43#include "xf86drm.h"
44 44
45#include "buffers.h" 45#include "buffers.h"
46 46
47#ifdef HAVE_CAIRO
48#include <math.h>
49#include <cairo.h>
50#endif
51
52#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
53
54struct bo 47struct bo
55{ 48{
56 int fd; 49 int fd;
@@ -62,956 +55,6 @@ struct bo
62}; 55};
63 56
64/* ----------------------------------------------------------------------------- 57/* -----------------------------------------------------------------------------
65 * Formats
66 */
67
68struct color_component {
69 unsigned int length;
70 unsigned int offset;
71};
72
73struct rgb_info {
74 struct color_component red;
75 struct color_component green;
76 struct color_component blue;
77 struct color_component alpha;
78};
79
80enum yuv_order {
81 YUV_YCbCr = 1,
82 YUV_YCrCb = 2,
83 YUV_YC = 4,
84 YUV_CY = 8,
85};
86
87struct yuv_info {
88 enum yuv_order order;
89 unsigned int xsub;
90 unsigned int ysub;
91 unsigned int chroma_stride;
92};
93
94struct format_info {
95 unsigned int format;
96 const char *name;
97 const struct rgb_info rgb;
98 const struct yuv_info yuv;
99};
100
101#define MAKE_RGB_INFO(rl, ro, bl, bo, gl, go, al, ao) \
102 .rgb = { { (rl), (ro) }, { (bl), (bo) }, { (gl), (go) }, { (al), (ao) } }
103
104#define MAKE_YUV_INFO(order, xsub, ysub, chroma_stride) \
105 .yuv = { (order), (xsub), (ysub), (chroma_stride) }
106
107static const struct format_info format_info[] = {
108 /* YUV packed */
109 { DRM_FORMAT_UYVY, "UYVY", MAKE_YUV_INFO(YUV_YCbCr | YUV_CY, 2, 2, 2) },
110 { DRM_FORMAT_VYUY, "VYUY", MAKE_YUV_INFO(YUV_YCrCb | YUV_CY, 2, 2, 2) },
111 { DRM_FORMAT_YUYV, "YUYV", MAKE_YUV_INFO(YUV_YCbCr | YUV_YC, 2, 2, 2) },
112 { DRM_FORMAT_YVYU, "YVYU", MAKE_YUV_INFO(YUV_YCrCb | YUV_YC, 2, 2, 2) },
113 /* YUV semi-planar */
114 { DRM_FORMAT_NV12, "NV12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 2) },
115 { DRM_FORMAT_NV21, "NV21", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 2) },
116 { DRM_FORMAT_NV16, "NV16", MAKE_YUV_INFO(YUV_YCbCr, 2, 1, 2) },
117 { DRM_FORMAT_NV61, "NV61", MAKE_YUV_INFO(YUV_YCrCb, 2, 1, 2) },
118 /* YUV planar */
119 { DRM_FORMAT_YUV420, "YU12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 1) },
120 { DRM_FORMAT_YVU420, "YV12", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 1) },
121 /* RGB16 */
122 { DRM_FORMAT_ARGB4444, "AR12", MAKE_RGB_INFO(4, 8, 4, 4, 4, 0, 4, 12) },
123 { DRM_FORMAT_XRGB4444, "XR12", MAKE_RGB_INFO(4, 8, 4, 4, 4, 0, 0, 0) },
124 { DRM_FORMAT_ABGR4444, "AB12", MAKE_RGB_INFO(4, 0, 4, 4, 4, 8, 4, 12) },
125 { DRM_FORMAT_XBGR4444, "XB12", MAKE_RGB_INFO(4, 0, 4, 4, 4, 8, 0, 0) },
126 { DRM_FORMAT_RGBA4444, "RA12", MAKE_RGB_INFO(4, 12, 4, 8, 4, 4, 4, 0) },
127 { DRM_FORMAT_RGBX4444, "RX12", MAKE_RGB_INFO(4, 12, 4, 8, 4, 4, 0, 0) },
128 { DRM_FORMAT_BGRA4444, "BA12", MAKE_RGB_INFO(4, 4, 4, 8, 4, 12, 4, 0) },
129 { DRM_FORMAT_BGRX4444, "BX12", MAKE_RGB_INFO(4, 4, 4, 8, 4, 12, 0, 0) },
130 { DRM_FORMAT_ARGB1555, "AR15", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 1, 15) },
131 { DRM_FORMAT_XRGB1555, "XR15", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 0, 0) },
132 { DRM_FORMAT_ABGR1555, "AB15", MAKE_RGB_INFO(5, 0, 5, 5, 5, 10, 1, 15) },
133 { DRM_FORMAT_XBGR1555, "XB15", MAKE_RGB_INFO(5, 0, 5, 5, 5, 10, 0, 0) },
134 { DRM_FORMAT_RGBA5551, "RA15", MAKE_RGB_INFO(5, 11, 5, 6, 5, 1, 1, 0) },
135 { DRM_FORMAT_RGBX5551, "RX15", MAKE_RGB_INFO(5, 11, 5, 6, 5, 1, 0, 0) },
136 { DRM_FORMAT_BGRA5551, "BA15", MAKE_RGB_INFO(5, 1, 5, 6, 5, 11, 1, 0) },
137 { DRM_FORMAT_BGRX5551, "BX15", MAKE_RGB_INFO(5, 1, 5, 6, 5, 11, 0, 0) },
138 { DRM_FORMAT_RGB565, "RG16", MAKE_RGB_INFO(5, 11, 6, 5, 5, 0, 0, 0) },
139 { DRM_FORMAT_BGR565, "BG16", MAKE_RGB_INFO(5, 0, 6, 5, 5, 11, 0, 0) },
140 /* RGB24 */
141 { DRM_FORMAT_BGR888, "BG24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 0, 0) },
142 { DRM_FORMAT_RGB888, "RG24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },
143 /* RGB32 */
144 { DRM_FORMAT_ARGB8888, "AR24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 8, 24) },
145 { DRM_FORMAT_XRGB8888, "XR24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },
146 { DRM_FORMAT_ABGR8888, "AB24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 8, 24) },
147 { DRM_FORMAT_XBGR8888, "XB24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 0, 0) },
148 { DRM_FORMAT_RGBA8888, "RA24", MAKE_RGB_INFO(8, 24, 8, 16, 8, 8, 8, 0) },
149 { DRM_FORMAT_RGBX8888, "RX24", MAKE_RGB_INFO(8, 24, 8, 16, 8, 8, 0, 0) },
150 { DRM_FORMAT_BGRA8888, "BA24", MAKE_RGB_INFO(8, 8, 8, 16, 8, 24, 8, 0) },
151 { DRM_FORMAT_BGRX8888, "BX24", MAKE_RGB_INFO(8, 8, 8, 16, 8, 24, 0, 0) },
152 { DRM_FORMAT_ARGB2101010, "AR30", MAKE_RGB_INFO(10, 20, 10, 10, 10, 0, 2, 30) },
153 { DRM_FORMAT_XRGB2101010, "XR30", MAKE_RGB_INFO(10, 20, 10, 10, 10, 0, 0, 0) },
154 { DRM_FORMAT_ABGR2101010, "AB30", MAKE_RGB_INFO(10, 0, 10, 10, 10, 20, 2, 30) },
155 { DRM_FORMAT_XBGR2101010, "XB30", MAKE_RGB_INFO(10, 0, 10, 10, 10, 20, 0, 0) },
156 { DRM_FORMAT_RGBA1010102, "RA30", MAKE_RGB_INFO(10, 22, 10, 12, 10, 2, 2, 0) },
157 { DRM_FORMAT_RGBX1010102, "RX30", MAKE_RGB_INFO(10, 22, 10, 12, 10, 2, 0, 0) },
158 { DRM_FORMAT_BGRA1010102, "BA30", MAKE_RGB_INFO(10, 2, 10, 12, 10, 22, 2, 0) },
159 { DRM_FORMAT_BGRX1010102, "BX30", MAKE_RGB_INFO(10, 2, 10, 12, 10, 22, 0, 0) },
160};
161
162unsigned int format_fourcc(const char *name)
163{
164 unsigned int i;
165 for (i = 0; i < ARRAY_SIZE(format_info); i++) {
166 if (!strcmp(format_info[i].name, name))
167 return format_info[i].format;
168 }
169 return 0;
170}
171
172/* -----------------------------------------------------------------------------
173 * Test patterns
174 */
175
176struct color_rgb24 {
177 unsigned int value:24;
178} __attribute__((__packed__));
179
180struct color_yuv {
181 unsigned char y;
182 unsigned char u;
183 unsigned char v;
184};
185
186#define MAKE_YUV_601_Y(r, g, b) \
187 ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16)
188#define MAKE_YUV_601_U(r, g, b) \
189 (((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128)
190#define MAKE_YUV_601_V(r, g, b) \
191 (((112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128)
192
193#define MAKE_YUV_601(r, g, b) \
194 { .y = MAKE_YUV_601_Y(r, g, b), \
195 .u = MAKE_YUV_601_U(r, g, b), \
196 .v = MAKE_YUV_601_V(r, g, b) }
197
198#define MAKE_RGBA(rgb, r, g, b, a) \
199 ((((r) >> (8 - (rgb)->red.length)) << (rgb)->red.offset) | \
200 (((g) >> (8 - (rgb)->green.length)) << (rgb)->green.offset) | \
201 (((b) >> (8 - (rgb)->blue.length)) << (rgb)->blue.offset) | \
202 (((a) >> (8 - (rgb)->alpha.length)) << (rgb)->alpha.offset))
203
204#define MAKE_RGB24(rgb, r, g, b) \
205 { .value = MAKE_RGBA(rgb, r, g, b, 0) }
206
207static void
208fill_smpte_yuv_planar(const struct yuv_info *yuv,
209 unsigned char *y_mem, unsigned char *u_mem,
210 unsigned char *v_mem, unsigned int width,
211 unsigned int height, unsigned int stride)
212{
213 const struct color_yuv colors_top[] = {
214 MAKE_YUV_601(191, 192, 192), /* grey */
215 MAKE_YUV_601(192, 192, 0), /* yellow */
216 MAKE_YUV_601(0, 192, 192), /* cyan */
217 MAKE_YUV_601(0, 192, 0), /* green */
218 MAKE_YUV_601(192, 0, 192), /* magenta */
219 MAKE_YUV_601(192, 0, 0), /* red */
220 MAKE_YUV_601(0, 0, 192), /* blue */
221 };
222 const struct color_yuv colors_middle[] = {
223 MAKE_YUV_601(0, 0, 192), /* blue */
224 MAKE_YUV_601(19, 19, 19), /* black */
225 MAKE_YUV_601(192, 0, 192), /* magenta */
226 MAKE_YUV_601(19, 19, 19), /* black */
227 MAKE_YUV_601(0, 192, 192), /* cyan */
228 MAKE_YUV_601(19, 19, 19), /* black */
229 MAKE_YUV_601(192, 192, 192), /* grey */
230 };
231 const struct color_yuv colors_bottom[] = {
232 MAKE_YUV_601(0, 33, 76), /* in-phase */
233 MAKE_YUV_601(255, 255, 255), /* super white */
234 MAKE_YUV_601(50, 0, 106), /* quadrature */
235 MAKE_YUV_601(19, 19, 19), /* black */
236 MAKE_YUV_601(9, 9, 9), /* 3.5% */
237 MAKE_YUV_601(19, 19, 19), /* 7.5% */
238 MAKE_YUV_601(29, 29, 29), /* 11.5% */
239 MAKE_YUV_601(19, 19, 19), /* black */
240 };
241 unsigned int cs = yuv->chroma_stride;
242 unsigned int xsub = yuv->xsub;
243 unsigned int ysub = yuv->ysub;
244 unsigned int x;
245 unsigned int y;
246
247 /* Luma */
248 for (y = 0; y < height * 6 / 9; ++y) {
249 for (x = 0; x < width; ++x)
250 y_mem[x] = colors_top[x * 7 / width].y;
251 y_mem += stride;
252 }
253
254 for (; y < height * 7 / 9; ++y) {
255 for (x = 0; x < width; ++x)
256 y_mem[x] = colors_middle[x * 7 / width].y;
257 y_mem += stride;
258 }
259
260 for (; y < height; ++y) {
261 for (x = 0; x < width * 5 / 7; ++x)
262 y_mem[x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
263 for (; x < width * 6 / 7; ++x)
264 y_mem[x] = colors_bottom[(x - width * 5 / 7) * 3
265 / (width / 7) + 4].y;
266 for (; x < width; ++x)
267 y_mem[x] = colors_bottom[7].y;
268 y_mem += stride;
269 }
270
271 /* Chroma */
272 for (y = 0; y < height / ysub * 6 / 9; ++y) {
273 for (x = 0; x < width; x += xsub) {
274 u_mem[x*cs/xsub] = colors_top[x * 7 / width].u;
275 v_mem[x*cs/xsub] = colors_top[x * 7 / width].v;
276 }
277 u_mem += stride * cs / xsub;
278 v_mem += stride * cs / xsub;
279 }
280
281 for (; y < height / ysub * 7 / 9; ++y) {
282 for (x = 0; x < width; x += xsub) {
283 u_mem[x*cs/xsub] = colors_middle[x * 7 / width].u;
284 v_mem[x*cs/xsub] = colors_middle[x * 7 / width].v;
285 }
286 u_mem += stride * cs / xsub;
287 v_mem += stride * cs / xsub;
288 }
289
290 for (; y < height / ysub; ++y) {
291 for (x = 0; x < width * 5 / 7; x += xsub) {
292 u_mem[x*cs/xsub] =
293 colors_bottom[x * 4 / (width * 5 / 7)].u;
294 v_mem[x*cs/xsub] =
295 colors_bottom[x * 4 / (width * 5 / 7)].v;
296 }
297 for (; x < width * 6 / 7; x += xsub) {
298 u_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
299 3 / (width / 7) + 4].u;
300 v_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
301 3 / (width / 7) + 4].v;
302 }
303 for (; x < width; x += xsub) {
304 u_mem[x*cs/xsub] = colors_bottom[7].u;
305 v_mem[x*cs/xsub] = colors_bottom[7].v;
306 }
307 u_mem += stride * cs / xsub;
308 v_mem += stride * cs / xsub;
309 }
310}
311
312static void
313fill_smpte_yuv_packed(const struct yuv_info *yuv, unsigned char *mem,
314 unsigned int width, unsigned int height,
315 unsigned int stride)
316{
317 const struct color_yuv colors_top[] = {
318 MAKE_YUV_601(191, 192, 192), /* grey */
319 MAKE_YUV_601(192, 192, 0), /* yellow */
320 MAKE_YUV_601(0, 192, 192), /* cyan */
321 MAKE_YUV_601(0, 192, 0), /* green */
322 MAKE_YUV_601(192, 0, 192), /* magenta */
323 MAKE_YUV_601(192, 0, 0), /* red */
324 MAKE_YUV_601(0, 0, 192), /* blue */
325 };
326 const struct color_yuv colors_middle[] = {
327 MAKE_YUV_601(0, 0, 192), /* blue */
328 MAKE_YUV_601(19, 19, 19), /* black */
329 MAKE_YUV_601(192, 0, 192), /* magenta */
330 MAKE_YUV_601(19, 19, 19), /* black */
331 MAKE_YUV_601(0, 192, 192), /* cyan */
332 MAKE_YUV_601(19, 19, 19), /* black */
333 MAKE_YUV_601(192, 192, 192), /* grey */
334 };
335 const struct color_yuv colors_bottom[] = {
336 MAKE_YUV_601(0, 33, 76), /* in-phase */
337 MAKE_YUV_601(255, 255, 255), /* super white */
338 MAKE_YUV_601(50, 0, 106), /* quadrature */
339 MAKE_YUV_601(19, 19, 19), /* black */
340 MAKE_YUV_601(9, 9, 9), /* 3.5% */
341 MAKE_YUV_601(19, 19, 19), /* 7.5% */
342 MAKE_YUV_601(29, 29, 29), /* 11.5% */
343 MAKE_YUV_601(19, 19, 19), /* black */
344 };
345 unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
346 unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
347 unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
348 unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
349 unsigned int x;
350 unsigned int y;
351
352 /* Luma */
353 for (y = 0; y < height * 6 / 9; ++y) {
354 for (x = 0; x < width; ++x)
355 y_mem[2*x] = colors_top[x * 7 / width].y;
356 y_mem += stride;
357 }
358
359 for (; y < height * 7 / 9; ++y) {
360 for (x = 0; x < width; ++x)
361 y_mem[2*x] = colors_middle[x * 7 / width].y;
362 y_mem += stride;
363 }
364
365 for (; y < height; ++y) {
366 for (x = 0; x < width * 5 / 7; ++x)
367 y_mem[2*x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
368 for (; x < width * 6 / 7; ++x)
369 y_mem[2*x] = colors_bottom[(x - width * 5 / 7) * 3
370 / (width / 7) + 4].y;
371 for (; x < width; ++x)
372 y_mem[2*x] = colors_bottom[7].y;
373 y_mem += stride;
374 }
375
376 /* Chroma */
377 for (y = 0; y < height * 6 / 9; ++y) {
378 for (x = 0; x < width; x += 2) {
379 c_mem[2*x+u] = colors_top[x * 7 / width].u;
380 c_mem[2*x+v] = colors_top[x * 7 / width].v;
381 }
382 c_mem += stride;
383 }
384
385 for (; y < height * 7 / 9; ++y) {
386 for (x = 0; x < width; x += 2) {
387 c_mem[2*x+u] = colors_middle[x * 7 / width].u;
388 c_mem[2*x+v] = colors_middle[x * 7 / width].v;
389 }
390 c_mem += stride;
391 }
392
393 for (; y < height; ++y) {
394 for (x = 0; x < width * 5 / 7; x += 2) {
395 c_mem[2*x+u] = colors_bottom[x * 4 / (width * 5 / 7)].u;
396 c_mem[2*x+v] = colors_bottom[x * 4 / (width * 5 / 7)].v;
397 }
398 for (; x < width * 6 / 7; x += 2) {
399 c_mem[2*x+u] = colors_bottom[(x - width * 5 / 7) *
400 3 / (width / 7) + 4].u;
401 c_mem[2*x+v] = colors_bottom[(x - width * 5 / 7) *
402 3 / (width / 7) + 4].v;
403 }
404 for (; x < width; x += 2) {
405 c_mem[2*x+u] = colors_bottom[7].u;
406 c_mem[2*x+v] = colors_bottom[7].v;
407 }
408 c_mem += stride;
409 }
410}
411
412static void
413fill_smpte_rgb16(const struct rgb_info *rgb, unsigned char *mem,
414 unsigned int width, unsigned int height, unsigned int stride)
415{
416 const uint16_t colors_top[] = {
417 MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
418 MAKE_RGBA(rgb, 192, 192, 0, 255), /* yellow */
419 MAKE_RGBA(rgb, 0, 192, 192, 255), /* cyan */
420 MAKE_RGBA(rgb, 0, 192, 0, 255), /* green */
421 MAKE_RGBA(rgb, 192, 0, 192, 255), /* magenta */
422 MAKE_RGBA(rgb, 192, 0, 0, 255), /* red */
423 MAKE_RGBA(rgb, 0, 0, 192, 255), /* blue */
424 };
425 const uint16_t colors_middle[] = {
426 MAKE_RGBA(rgb, 0, 0, 192, 255), /* blue */
427 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
428 MAKE_RGBA(rgb, 192, 0, 192, 255), /* magenta */
429 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
430 MAKE_RGBA(rgb, 0, 192, 192, 255), /* cyan */
431 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
432 MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
433 };
434 const uint16_t colors_bottom[] = {
435 MAKE_RGBA(rgb, 0, 33, 76, 255), /* in-phase */
436 MAKE_RGBA(rgb, 255, 255, 255, 255), /* super white */
437 MAKE_RGBA(rgb, 50, 0, 106, 255), /* quadrature */
438 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
439 MAKE_RGBA(rgb, 9, 9, 9, 255), /* 3.5% */
440 MAKE_RGBA(rgb, 19, 19, 19, 255), /* 7.5% */
441 MAKE_RGBA(rgb, 29, 29, 29, 255), /* 11.5% */
442 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
443 };
444 unsigned int x;
445 unsigned int y;
446
447 for (y = 0; y < height * 6 / 9; ++y) {
448 for (x = 0; x < width; ++x)
449 ((uint16_t *)mem)[x] = colors_top[x * 7 / width];
450 mem += stride;
451 }
452
453 for (; y < height * 7 / 9; ++y) {
454 for (x = 0; x < width; ++x)
455 ((uint16_t *)mem)[x] = colors_middle[x * 7 / width];
456 mem += stride;
457 }
458
459 for (; y < height; ++y) {
460 for (x = 0; x < width * 5 / 7; ++x)
461 ((uint16_t *)mem)[x] =
462 colors_bottom[x * 4 / (width * 5 / 7)];
463 for (; x < width * 6 / 7; ++x)
464 ((uint16_t *)mem)[x] =
465 colors_bottom[(x - width * 5 / 7) * 3
466 / (width / 7) + 4];
467 for (; x < width; ++x)
468 ((uint16_t *)mem)[x] = colors_bottom[7];
469 mem += stride;
470 }
471}
472
473static void
474fill_smpte_rgb24(const struct rgb_info *rgb, void *mem,
475 unsigned int width, unsigned int height, unsigned int stride)
476{
477 const struct color_rgb24 colors_top[] = {
478 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
479 MAKE_RGB24(rgb, 192, 192, 0), /* yellow */
480 MAKE_RGB24(rgb, 0, 192, 192), /* cyan */
481 MAKE_RGB24(rgb, 0, 192, 0), /* green */
482 MAKE_RGB24(rgb, 192, 0, 192), /* magenta */
483 MAKE_RGB24(rgb, 192, 0, 0), /* red */
484 MAKE_RGB24(rgb, 0, 0, 192), /* blue */
485 };
486 const struct color_rgb24 colors_middle[] = {
487 MAKE_RGB24(rgb, 0, 0, 192), /* blue */
488 MAKE_RGB24(rgb, 19, 19, 19), /* black */
489 MAKE_RGB24(rgb, 192, 0, 192), /* magenta */
490 MAKE_RGB24(rgb, 19, 19, 19), /* black */
491 MAKE_RGB24(rgb, 0, 192, 192), /* cyan */
492 MAKE_RGB24(rgb, 19, 19, 19), /* black */
493 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
494 };
495 const struct color_rgb24 colors_bottom[] = {
496 MAKE_RGB24(rgb, 0, 33, 76), /* in-phase */
497 MAKE_RGB24(rgb, 255, 255, 255), /* super white */
498 MAKE_RGB24(rgb, 50, 0, 106), /* quadrature */
499 MAKE_RGB24(rgb, 19, 19, 19), /* black */
500 MAKE_RGB24(rgb, 9, 9, 9), /* 3.5% */
501 MAKE_RGB24(rgb, 19, 19, 19), /* 7.5% */
502 MAKE_RGB24(rgb, 29, 29, 29), /* 11.5% */
503 MAKE_RGB24(rgb, 19, 19, 19), /* black */
504 };
505 unsigned int x;
506 unsigned int y;
507
508 for (y = 0; y < height * 6 / 9; ++y) {
509 for (x = 0; x < width; ++x)
510 ((struct color_rgb24 *)mem)[x] =
511 colors_top[x * 7 / width];
512 mem += stride;
513 }
514
515 for (; y < height * 7 / 9; ++y) {
516 for (x = 0; x < width; ++x)
517 ((struct color_rgb24 *)mem)[x] =
518 colors_middle[x * 7 / width];
519 mem += stride;
520 }
521
522 for (; y < height; ++y) {
523 for (x = 0; x < width * 5 / 7; ++x)
524 ((struct color_rgb24 *)mem)[x] =
525 colors_bottom[x * 4 / (width * 5 / 7)];
526 for (; x < width * 6 / 7; ++x)
527 ((struct color_rgb24 *)mem)[x] =
528 colors_bottom[(x - width * 5 / 7) * 3
529 / (width / 7) + 4];
530 for (; x < width; ++x)
531 ((struct color_rgb24 *)mem)[x] = colors_bottom[7];
532 mem += stride;
533 }
534}
535
536static void
537fill_smpte_rgb32(const struct rgb_info *rgb, unsigned char *mem,
538 unsigned int width, unsigned int height, unsigned int stride)
539{
540 const uint32_t colors_top[] = {
541 MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
542 MAKE_RGBA(rgb, 192, 192, 0, 255), /* yellow */
543 MAKE_RGBA(rgb, 0, 192, 192, 255), /* cyan */
544 MAKE_RGBA(rgb, 0, 192, 0, 255), /* green */
545 MAKE_RGBA(rgb, 192, 0, 192, 255), /* magenta */
546 MAKE_RGBA(rgb, 192, 0, 0, 255), /* red */
547 MAKE_RGBA(rgb, 0, 0, 192, 255), /* blue */
548 };
549 const uint32_t colors_middle[] = {
550 MAKE_RGBA(rgb, 0, 0, 192, 255), /* blue */
551 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
552 MAKE_RGBA(rgb, 192, 0, 192, 255), /* magenta */
553 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
554 MAKE_RGBA(rgb, 0, 192, 192, 255), /* cyan */
555 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
556 MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
557 };
558 const uint32_t colors_bottom[] = {
559 MAKE_RGBA(rgb, 0, 33, 76, 255), /* in-phase */
560 MAKE_RGBA(rgb, 255, 255, 255, 255), /* super white */
561 MAKE_RGBA(rgb, 50, 0, 106, 255), /* quadrature */
562 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
563 MAKE_RGBA(rgb, 9, 9, 9, 255), /* 3.5% */
564 MAKE_RGBA(rgb, 19, 19, 19, 255), /* 7.5% */
565 MAKE_RGBA(rgb, 29, 29, 29, 255), /* 11.5% */
566 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
567 };
568 unsigned int x;
569 unsigned int y;
570
571 for (y = 0; y < height * 6 / 9; ++y) {
572 for (x = 0; x < width; ++x)
573 ((uint32_t *)mem)[x] = colors_top[x * 7 / width];
574 mem += stride;
575 }
576
577 for (; y < height * 7 / 9; ++y) {
578 for (x = 0; x < width; ++x)
579 ((uint32_t *)mem)[x] = colors_middle[x * 7 / width];
580 mem += stride;
581 }
582
583 for (; y < height; ++y) {
584 for (x = 0; x < width * 5 / 7; ++x)
585 ((uint32_t *)mem)[x] =
586 colors_bottom[x * 4 / (width * 5 / 7)];
587 for (; x < width * 6 / 7; ++x)
588 ((uint32_t *)mem)[x] =
589 colors_bottom[(x - width * 5 / 7) * 3
590 / (width / 7) + 4];
591 for (; x < width; ++x)
592 ((uint32_t *)mem)[x] = colors_bottom[7];
593 mem += stride;
594 }
595}
596
597static void
598fill_smpte(const struct format_info *info, void *planes[3], unsigned int width,
599 unsigned int height, unsigned int stride)
600{
601 unsigned char *u, *v;
602
603 switch (info->format) {
604 case DRM_FORMAT_UYVY:
605 case DRM_FORMAT_VYUY:
606 case DRM_FORMAT_YUYV:
607 case DRM_FORMAT_YVYU:
608 return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
609 height, stride);
610
611 case DRM_FORMAT_NV12:
612 case DRM_FORMAT_NV21:
613 case DRM_FORMAT_NV16:
614 case DRM_FORMAT_NV61:
615 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
616 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
617 return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
618 width, height, stride);
619
620 case DRM_FORMAT_YUV420:
621 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
622 planes[2], width, height, stride);
623
624 case DRM_FORMAT_YVU420:
625 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[2],
626 planes[1], width, height, stride);
627
628 case DRM_FORMAT_ARGB4444:
629 case DRM_FORMAT_XRGB4444:
630 case DRM_FORMAT_ABGR4444:
631 case DRM_FORMAT_XBGR4444:
632 case DRM_FORMAT_RGBA4444:
633 case DRM_FORMAT_RGBX4444:
634 case DRM_FORMAT_BGRA4444:
635 case DRM_FORMAT_BGRX4444:
636 case DRM_FORMAT_RGB565:
637 case DRM_FORMAT_BGR565:
638 case DRM_FORMAT_ARGB1555:
639 case DRM_FORMAT_XRGB1555:
640 case DRM_FORMAT_ABGR1555:
641 case DRM_FORMAT_XBGR1555:
642 case DRM_FORMAT_RGBA5551:
643 case DRM_FORMAT_RGBX5551:
644 case DRM_FORMAT_BGRA5551:
645 case DRM_FORMAT_BGRX5551:
646 return fill_smpte_rgb16(&info->rgb, planes[0],
647 width, height, stride);
648
649 case DRM_FORMAT_BGR888:
650 case DRM_FORMAT_RGB888:
651 return fill_smpte_rgb24(&info->rgb, planes[0],
652 width, height, stride);
653 case DRM_FORMAT_ARGB8888:
654 case DRM_FORMAT_XRGB8888:
655 case DRM_FORMAT_ABGR8888:
656 case DRM_FORMAT_XBGR8888:
657 case DRM_FORMAT_RGBA8888:
658 case DRM_FORMAT_RGBX8888:
659 case DRM_FORMAT_BGRA8888:
660 case DRM_FORMAT_BGRX8888:
661 case DRM_FORMAT_ARGB2101010:
662 case DRM_FORMAT_XRGB2101010:
663 case DRM_FORMAT_ABGR2101010:
664 case DRM_FORMAT_XBGR2101010:
665 case DRM_FORMAT_RGBA1010102:
666 case DRM_FORMAT_RGBX1010102:
667 case DRM_FORMAT_BGRA1010102:
668 case DRM_FORMAT_BGRX1010102:
669 return fill_smpte_rgb32(&info->rgb, planes[0],
670 width, height, stride);
671 }
672}
673
674/* swap these for big endian.. */
675#define RED 2
676#define GREEN 1
677#define BLUE 0
678
679static void
680make_pwetty(void *data, int width, int height, int stride, uint32_t format)
681{
682#ifdef HAVE_CAIRO
683 cairo_surface_t *surface;
684 cairo_t *cr;
685 int x, y;
686 cairo_format_t cairo_format;
687
688 /* we can ignore the order of R,G,B channels */
689 switch (format) {
690 case DRM_FORMAT_XRGB8888:
691 case DRM_FORMAT_ARGB8888:
692 case DRM_FORMAT_XBGR8888:
693 case DRM_FORMAT_ABGR8888:
694 cairo_format = CAIRO_FORMAT_ARGB32;
695 break;
696 case DRM_FORMAT_RGB565:
697 case DRM_FORMAT_BGR565:
698 cairo_format = CAIRO_FORMAT_RGB16_565;
699 break;
700 default:
701 return;
702 }
703
704 surface = cairo_image_surface_create_for_data(data,
705 cairo_format,
706 width, height,
707 stride);
708 cr = cairo_create(surface);
709 cairo_surface_destroy(surface);
710
711 cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
712 for (x = 0; x < width; x += 250)
713 for (y = 0; y < height; y += 250) {
714 char buf[64];
715
716 cairo_move_to(cr, x, y - 20);
717 cairo_line_to(cr, x, y + 20);
718 cairo_move_to(cr, x - 20, y);
719 cairo_line_to(cr, x + 20, y);
720 cairo_new_sub_path(cr);
721 cairo_arc(cr, x, y, 10, 0, M_PI * 2);
722 cairo_set_line_width(cr, 4);
723 cairo_set_source_rgb(cr, 0, 0, 0);
724 cairo_stroke_preserve(cr);
725 cairo_set_source_rgb(cr, 1, 1, 1);
726 cairo_set_line_width(cr, 2);
727 cairo_stroke(cr);
728
729 snprintf(buf, sizeof buf, "%d, %d", x, y);
730 cairo_move_to(cr, x + 20, y + 20);
731 cairo_text_path(cr, buf);
732 cairo_set_source_rgb(cr, 0, 0, 0);
733 cairo_stroke_preserve(cr);
734 cairo_set_source_rgb(cr, 1, 1, 1);
735 cairo_fill(cr);
736 }
737
738 cairo_destroy(cr);
739#endif
740}
741
742static void
743fill_tiles_yuv_planar(const struct format_info *info,
744 unsigned char *y_mem, unsigned char *u_mem,
745 unsigned char *v_mem, unsigned int width,
746 unsigned int height, unsigned int stride)
747{
748 const struct yuv_info *yuv = &info->yuv;
749 unsigned int cs = yuv->chroma_stride;
750 unsigned int xsub = yuv->xsub;
751 unsigned int ysub = yuv->ysub;
752 unsigned int x;
753 unsigned int y;
754
755 for (y = 0; y < height; ++y) {
756 for (x = 0; x < width; ++x) {
757 div_t d = div(x+y, width);
758 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
759 + 0x000a1120 * (d.rem >> 6);
760 struct color_yuv color =
761 MAKE_YUV_601((rgb32 >> 16) & 0xff,
762 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
763
764 y_mem[x] = color.y;
765 u_mem[x/xsub*cs] = color.u;
766 v_mem[x/xsub*cs] = color.v;
767 }
768
769 y_mem += stride;
770 if ((y + 1) % ysub == 0) {
771 u_mem += stride * cs / xsub;
772 v_mem += stride * cs / xsub;
773 }
774 }
775}
776
777static void
778fill_tiles_yuv_packed(const struct format_info *info, unsigned char *mem,
779 unsigned int width, unsigned int height,
780 unsigned int stride)
781{
782 const struct yuv_info *yuv = &info->yuv;
783 unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
784 unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
785 unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
786 unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
787 unsigned int x;
788 unsigned int y;
789
790 for (y = 0; y < height; ++y) {
791 for (x = 0; x < width; x += 2) {
792 div_t d = div(x+y, width);
793 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
794 + 0x000a1120 * (d.rem >> 6);
795 struct color_yuv color =
796 MAKE_YUV_601((rgb32 >> 16) & 0xff,
797 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
798
799 y_mem[2*x] = color.y;
800 c_mem[2*x+u] = color.u;
801 y_mem[2*x+2] = color.y;
802 c_mem[2*x+v] = color.v;
803 }
804
805 y_mem += stride;
806 c_mem += stride;
807 }
808}
809
810static void
811fill_tiles_rgb16(const struct format_info *info, unsigned char *mem,
812 unsigned int width, unsigned int height, unsigned int stride)
813{
814 const struct rgb_info *rgb = &info->rgb;
815 unsigned char *mem_base = mem;
816 unsigned int x, y;
817
818 for (y = 0; y < height; ++y) {
819 for (x = 0; x < width; ++x) {
820 div_t d = div(x+y, width);
821 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
822 + 0x000a1120 * (d.rem >> 6);
823 uint16_t color =
824 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
825 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
826 255);
827
828 ((uint16_t *)mem)[x] = color;
829 }
830 mem += stride;
831 }
832
833 make_pwetty(mem_base, width, height, stride, info->format);
834}
835
836static void
837fill_tiles_rgb24(const struct format_info *info, unsigned char *mem,
838 unsigned int width, unsigned int height, unsigned int stride)
839{
840 const struct rgb_info *rgb = &info->rgb;
841 unsigned int x, y;
842
843 for (y = 0; y < height; ++y) {
844 for (x = 0; x < width; ++x) {
845 div_t d = div(x+y, width);
846 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
847 + 0x000a1120 * (d.rem >> 6);
848 struct color_rgb24 color =
849 MAKE_RGB24(rgb, (rgb32 >> 16) & 0xff,
850 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
851
852 ((struct color_rgb24 *)mem)[x] = color;
853 }
854 mem += stride;
855 }
856}
857
858static void
859fill_tiles_rgb32(const struct format_info *info, unsigned char *mem,
860 unsigned int width, unsigned int height, unsigned int stride)
861{
862 const struct rgb_info *rgb = &info->rgb;
863 unsigned char *mem_base = mem;
864 unsigned int x, y;
865
866 for (y = 0; y < height; ++y) {
867 for (x = 0; x < width; ++x) {
868 div_t d = div(x+y, width);
869 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
870 + 0x000a1120 * (d.rem >> 6);
871 uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
872 uint32_t color =
873 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
874 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
875 alpha);
876
877 ((uint32_t *)mem)[x] = color;
878 }
879 mem += stride;
880 }
881
882 make_pwetty(mem_base, width, height, stride, info->format);
883}
884
885static void
886fill_tiles(const struct format_info *info, void *planes[3], unsigned int width,
887 unsigned int height, unsigned int stride)
888{
889 unsigned char *u, *v;
890
891 switch (info->format) {
892 case DRM_FORMAT_UYVY:
893 case DRM_FORMAT_VYUY:
894 case DRM_FORMAT_YUYV:
895 case DRM_FORMAT_YVYU:
896 return fill_tiles_yuv_packed(info, planes[0],
897 width, height, stride);
898
899 case DRM_FORMAT_NV12:
900 case DRM_FORMAT_NV21:
901 case DRM_FORMAT_NV16:
902 case DRM_FORMAT_NV61:
903 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
904 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
905 return fill_tiles_yuv_planar(info, planes[0], u, v,
906 width, height, stride);
907
908 case DRM_FORMAT_YUV420:
909 return fill_tiles_yuv_planar(info, planes[0], planes[1],
910 planes[2], width, height, stride);
911
912 case DRM_FORMAT_YVU420:
913 return fill_tiles_yuv_planar(info, planes[0], planes[2],
914 planes[1], width, height, stride);
915
916 case DRM_FORMAT_ARGB4444:
917 case DRM_FORMAT_XRGB4444:
918 case DRM_FORMAT_ABGR4444:
919 case DRM_FORMAT_XBGR4444:
920 case DRM_FORMAT_RGBA4444:
921 case DRM_FORMAT_RGBX4444:
922 case DRM_FORMAT_BGRA4444:
923 case DRM_FORMAT_BGRX4444:
924 case DRM_FORMAT_RGB565:
925 case DRM_FORMAT_BGR565:
926 case DRM_FORMAT_ARGB1555:
927 case DRM_FORMAT_XRGB1555:
928 case DRM_FORMAT_ABGR1555:
929 case DRM_FORMAT_XBGR1555:
930 case DRM_FORMAT_RGBA5551:
931 case DRM_FORMAT_RGBX5551:
932 case DRM_FORMAT_BGRA5551:
933 case DRM_FORMAT_BGRX5551:
934 return fill_tiles_rgb16(info, planes[0],
935 width, height, stride);
936
937 case DRM_FORMAT_BGR888:
938 case DRM_FORMAT_RGB888:
939 return fill_tiles_rgb24(info, planes[0],
940 width, height, stride);
941 case DRM_FORMAT_ARGB8888:
942 case DRM_FORMAT_XRGB8888:
943 case DRM_FORMAT_ABGR8888:
944 case DRM_FORMAT_XBGR8888:
945 case DRM_FORMAT_RGBA8888:
946 case DRM_FORMAT_RGBX8888:
947 case DRM_FORMAT_BGRA8888:
948 case DRM_FORMAT_BGRX8888:
949 case DRM_FORMAT_ARGB2101010:
950 case DRM_FORMAT_XRGB2101010:
951 case DRM_FORMAT_ABGR2101010:
952 case DRM_FORMAT_XBGR2101010:
953 case DRM_FORMAT_RGBA1010102:
954 case DRM_FORMAT_RGBX1010102:
955 case DRM_FORMAT_BGRA1010102:
956 case DRM_FORMAT_BGRX1010102:
957 return fill_tiles_rgb32(info, planes[0],
958 width, height, stride);
959 }
960}
961
962static void
963fill_plain(const struct format_info *info, void *planes[3], unsigned int width,
964 unsigned int height, unsigned int stride)
965{
966 memset(planes[0], 0x77, stride * height);
967}
968
969/*
970 * fill_pattern - Fill a buffer with a test pattern
971 * @format: Pixel format
972 * @pattern: Test pattern
973 * @buffer: Buffer memory
974 * @width: Width in pixels
975 * @height: Height in pixels
976 * @stride: Line stride (pitch) in bytes
977 *
978 * Fill the buffer with the test pattern specified by the pattern parameter.
979 * Supported formats vary depending on the selected pattern.
980 */
981static void
982fill_pattern(unsigned int format, enum fill_pattern pattern, void *planes[3],
983 unsigned int width, unsigned int height, unsigned int stride)
984{
985 const struct format_info *info = NULL;
986 unsigned int i;
987
988 for (i = 0; i < ARRAY_SIZE(format_info); ++i) {
989 if (format_info[i].format == format) {
990 info = &format_info[i];
991 break;
992 }
993 }
994
995 if (info == NULL)
996 return;
997
998 switch (pattern) {
999 case PATTERN_TILES:
1000 return fill_tiles(info, planes, width, height, stride);
1001
1002 case PATTERN_SMPTE:
1003 return fill_smpte(info, planes, width, height, stride);
1004
1005 case PATTERN_PLAIN:
1006 return fill_plain(info, planes, width, height, stride);
1007
1008 default:
1009 printf("Error: unsupported test pattern %u.\n", pattern);
1010 break;
1011 }
1012}
1013
1014/* -----------------------------------------------------------------------------
1015 * Buffers management 58 * Buffers management
1016 */ 59 */
1017 60
@@ -1022,7 +65,7 @@ bo_create_dumb(int fd, unsigned int width, unsigned int height, unsigned int bpp
1022 struct bo *bo; 65 struct bo *bo;
1023 int ret; 66 int ret;
1024 67
1025 bo = malloc(sizeof(*bo)); 68 bo = calloc(1, sizeof(*bo));
1026 if (bo == NULL) { 69 if (bo == NULL) {
1027 fprintf(stderr, "failed to allocate buffer object\n"); 70 fprintf(stderr, "failed to allocate buffer object\n");
1028 return NULL; 71 return NULL;
@@ -1086,7 +129,7 @@ struct bo *
1086bo_create(int fd, unsigned int format, 129bo_create(int fd, unsigned int format,
1087 unsigned int width, unsigned int height, 130 unsigned int width, unsigned int height,
1088 unsigned int handles[4], unsigned int pitches[4], 131 unsigned int handles[4], unsigned int pitches[4],
1089 unsigned int offsets[4], enum fill_pattern pattern) 132 unsigned int offsets[4], enum util_fill_pattern pattern)
1090{ 133{
1091 unsigned int virtual_height; 134 unsigned int virtual_height;
1092 struct bo *bo; 135 struct bo *bo;
@@ -1162,6 +205,8 @@ bo_create(int fd, unsigned int format,
1162 switch (format) { 205 switch (format) {
1163 case DRM_FORMAT_NV12: 206 case DRM_FORMAT_NV12:
1164 case DRM_FORMAT_NV21: 207 case DRM_FORMAT_NV21:
208 case DRM_FORMAT_YUV420:
209 case DRM_FORMAT_YVU420:
1165 virtual_height = height * 3 / 2; 210 virtual_height = height * 3 / 2;
1166 break; 211 break;
1167 212
@@ -1278,7 +323,7 @@ bo_create(int fd, unsigned int format,
1278 break; 323 break;
1279 } 324 }
1280 325
1281 fill_pattern(format, pattern, planes, width, height, pitches[0]); 326 util_fill_pattern(format, pattern, planes, width, height, pitches[0]);
1282 bo_unmap(bo); 327 bo_unmap(bo);
1283 328
1284 return bo; 329 return bo;
diff --git a/tests/modetest/buffers.h b/tests/modetest/buffers.h
index ad73d0e4..7f95396b 100644
--- a/tests/modetest/buffers.h
+++ b/tests/modetest/buffers.h
@@ -27,20 +27,14 @@
27#ifndef __BUFFERS_H__ 27#ifndef __BUFFERS_H__
28#define __BUFFERS_H__ 28#define __BUFFERS_H__
29 29
30struct bo; 30#include "util/pattern.h"
31 31
32enum fill_pattern { 32struct bo;
33 PATTERN_TILES = 0,
34 PATTERN_PLAIN = 1,
35 PATTERN_SMPTE = 2,
36};
37 33
38struct bo *bo_create(int fd, unsigned int format, 34struct bo *bo_create(int fd, unsigned int format,
39 unsigned int width, unsigned int height, 35 unsigned int width, unsigned int height,
40 unsigned int handles[4], unsigned int pitches[4], 36 unsigned int handles[4], unsigned int pitches[4],
41 unsigned int offsets[4], enum fill_pattern pattern); 37 unsigned int offsets[4], enum util_fill_pattern pattern);
42void bo_destroy(struct bo *bo); 38void bo_destroy(struct bo *bo);
43 39
44unsigned int format_fourcc(const char *name);
45
46#endif 40#endif
diff --git a/tests/modetest/cursor.c b/tests/modetest/cursor.c
index 62a50efb..6de82a4a 100644
--- a/tests/modetest/cursor.c
+++ b/tests/modetest/cursor.c
@@ -40,11 +40,11 @@
40#include "xf86drm.h" 40#include "xf86drm.h"
41#include "xf86drmMode.h" 41#include "xf86drmMode.h"
42 42
43#include "util/common.h"
44
43#include "buffers.h" 45#include "buffers.h"
44#include "cursor.h" 46#include "cursor.h"
45 47
46#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
47
48struct cursor { 48struct cursor {
49 int fd; 49 int fd;
50 uint32_t bo_handle; 50 uint32_t bo_handle;
@@ -70,7 +70,7 @@ static int cursor_running;
70 */ 70 */
71 71
72struct cursor_step { 72struct cursor_step {
73 void (*run)(struct cursor *cursor, struct cursor_step *step); 73 void (*run)(struct cursor *cursor, const struct cursor_step *step);
74 uint32_t msec; 74 uint32_t msec;
75 uint32_t repeat; 75 uint32_t repeat;
76 int arg; 76 int arg;
@@ -78,7 +78,7 @@ struct cursor_step {
78 78
79static uint32_t indx, count; 79static uint32_t indx, count;
80 80
81static void set_cursor(struct cursor *cursor, struct cursor_step *step) 81static void set_cursor(struct cursor *cursor, const struct cursor_step *step)
82{ 82{
83 int enabled = (step->arg ^ count) & 0x1; 83 int enabled = (step->arg ^ count) & 0x1;
84 uint32_t handle = 0; 84 uint32_t handle = 0;
@@ -91,7 +91,7 @@ static void set_cursor(struct cursor *cursor, struct cursor_step *step)
91 drmModeSetCursor(cursor->fd, cursor->crtc_id, handle, cursor->w, cursor->h); 91 drmModeSetCursor(cursor->fd, cursor->crtc_id, handle, cursor->w, cursor->h);
92} 92}
93 93
94static void move_cursor(struct cursor *cursor, struct cursor_step *step) 94static void move_cursor(struct cursor *cursor, const struct cursor_step *step)
95{ 95{
96 int x = cursor->x; 96 int x = cursor->x;
97 int y = cursor->y; 97 int y = cursor->y;
@@ -126,7 +126,7 @@ static void move_cursor(struct cursor *cursor, struct cursor_step *step)
126 drmModeMoveCursor(cursor->fd, cursor->crtc_id, x, y); 126 drmModeMoveCursor(cursor->fd, cursor->crtc_id, x, y);
127} 127}
128 128
129static struct cursor_step steps[] = { 129static const struct cursor_step steps[] = {
130 { set_cursor, 10, 0, 1 }, /* enable */ 130 { set_cursor, 10, 0, 1 }, /* enable */
131 { move_cursor, 1, 100, 1 }, 131 { move_cursor, 1, 100, 1 },
132 { move_cursor, 1, 10, 10 }, 132 { move_cursor, 1, 10, 10 },
@@ -145,7 +145,7 @@ static struct cursor_step steps[] = {
145static void *cursor_thread_func(void *data) 145static void *cursor_thread_func(void *data)
146{ 146{
147 while (cursor_running) { 147 while (cursor_running) {
148 struct cursor_step *step = &steps[indx % ARRAY_SIZE(steps)]; 148 const struct cursor_step *step = &steps[indx % ARRAY_SIZE(steps)];
149 int i; 149 int i;
150 150
151 for (i = 0; i < ncursors; i++) { 151 for (i = 0; i < ncursors; i++) {
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 8c0db6db..2c5b2830 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -37,6 +37,7 @@
37 * TODO: use cairo to write the mode info on the selected output once 37 * TODO: use cairo to write the mode info on the selected output once
38 * the mode has been programmed, along with possible test patterns. 38 * the mode has been programmed, along with possible test patterns.
39 */ 39 */
40
40#ifdef HAVE_CONFIG_H 41#ifdef HAVE_CONFIG_H
41#include "config.h" 42#include "config.h"
42#endif 43#endif
@@ -59,6 +60,11 @@
59#include "xf86drmMode.h" 60#include "xf86drmMode.h"
60#include "drm_fourcc.h" 61#include "drm_fourcc.h"
61 62
63#include "util/common.h"
64#include "util/format.h"
65#include "util/kms.h"
66#include "util/pattern.h"
67
62#include "buffers.h" 68#include "buffers.h"
63#include "cursor.h" 69#include "cursor.h"
64 70
@@ -77,6 +83,7 @@ struct connector {
77 drmModeConnector *connector; 83 drmModeConnector *connector;
78 drmModeObjectProperties *props; 84 drmModeObjectProperties *props;
79 drmModePropertyRes **props_info; 85 drmModePropertyRes **props_info;
86 char *name;
80}; 87};
81 88
82struct fb { 89struct fb {
@@ -111,68 +118,15 @@ struct device {
111 118
112 unsigned int fb_id; 119 unsigned int fb_id;
113 struct bo *bo; 120 struct bo *bo;
121 struct bo *cursor_bo;
114 } mode; 122 } mode;
115}; 123};
116 124
117#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
118static inline int64_t U642I64(uint64_t val) 125static inline int64_t U642I64(uint64_t val)
119{ 126{
120 return (int64_t)*((int64_t *)&val); 127 return (int64_t)*((int64_t *)&val);
121} 128}
122 129
123struct type_name {
124 int type;
125 const char *name;
126};
127
128#define type_name_fn(res) \
129const char * res##_str(int type) { \
130 unsigned int i; \
131 for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
132 if (res##_names[i].type == type) \
133 return res##_names[i].name; \
134 } \
135 return "(invalid)"; \
136}
137
138struct type_name encoder_type_names[] = {
139 { DRM_MODE_ENCODER_NONE, "none" },
140 { DRM_MODE_ENCODER_DAC, "DAC" },
141 { DRM_MODE_ENCODER_TMDS, "TMDS" },
142 { DRM_MODE_ENCODER_LVDS, "LVDS" },
143 { DRM_MODE_ENCODER_TVDAC, "TVDAC" },
144};
145
146static type_name_fn(encoder_type)
147
148struct type_name connector_status_names[] = {
149 { DRM_MODE_CONNECTED, "connected" },
150 { DRM_MODE_DISCONNECTED, "disconnected" },
151 { DRM_MODE_UNKNOWNCONNECTION, "unknown" },
152};
153
154static type_name_fn(connector_status)
155
156struct type_name connector_type_names[] = {
157 { DRM_MODE_CONNECTOR_Unknown, "unknown" },
158 { DRM_MODE_CONNECTOR_VGA, "VGA" },
159 { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
160 { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
161 { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
162 { DRM_MODE_CONNECTOR_Composite, "composite" },
163 { DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
164 { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
165 { DRM_MODE_CONNECTOR_Component, "component" },
166 { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
167 { DRM_MODE_CONNECTOR_DisplayPort, "DP" },
168 { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
169 { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
170 { DRM_MODE_CONNECTOR_TV, "TV" },
171 { DRM_MODE_CONNECTOR_eDP, "eDP" },
172};
173
174static type_name_fn(connector_type)
175
176#define bit_name_fn(res) \ 130#define bit_name_fn(res) \
177const char * res##_str(int type) { \ 131const char * res##_str(int type) { \
178 unsigned int i; \ 132 unsigned int i; \
@@ -232,7 +186,7 @@ static void dump_encoders(struct device *dev)
232 printf("%d\t%d\t%s\t0x%08x\t0x%08x\n", 186 printf("%d\t%d\t%s\t0x%08x\t0x%08x\n",
233 encoder->encoder_id, 187 encoder->encoder_id,
234 encoder->crtc_id, 188 encoder->crtc_id,
235 encoder_type_str(encoder->encoder_type), 189 util_lookup_encoder_type_name(encoder->encoder_type),
236 encoder->possible_crtcs, 190 encoder->possible_crtcs,
237 encoder->possible_clones); 191 encoder->possible_clones);
238 } 192 }
@@ -366,18 +320,18 @@ static void dump_connectors(struct device *dev)
366 int i, j; 320 int i, j;
367 321
368 printf("Connectors:\n"); 322 printf("Connectors:\n");
369 printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n"); 323 printf("id\tencoder\tstatus\t\tname\t\tsize (mm)\tmodes\tencoders\n");
370 for (i = 0; i < dev->resources->res->count_connectors; i++) { 324 for (i = 0; i < dev->resources->res->count_connectors; i++) {
371 struct connector *_connector = &dev->resources->connectors[i]; 325 struct connector *_connector = &dev->resources->connectors[i];
372 drmModeConnector *connector = _connector->connector; 326 drmModeConnector *connector = _connector->connector;
373 if (!connector) 327 if (!connector)
374 continue; 328 continue;
375 329
376 printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t", 330 printf("%d\t%d\t%s\t%-15s\t%dx%d\t\t%d\t",
377 connector->connector_id, 331 connector->connector_id,
378 connector->encoder_id, 332 connector->encoder_id,
379 connector_status_str(connector->connection), 333 util_lookup_connector_status_name(connector->connection),
380 connector_type_str(connector->connector_type), 334 _connector->name,
381 connector->mmWidth, connector->mmHeight, 335 connector->mmWidth, connector->mmHeight,
382 connector->count_modes); 336 connector->count_modes);
383 337
@@ -503,12 +457,13 @@ static void dump_planes(struct device *dev)
503 457
504static void free_resources(struct resources *res) 458static void free_resources(struct resources *res)
505{ 459{
460 int i;
461
506 if (!res) 462 if (!res)
507 return; 463 return;
508 464
509#define free_resource(_res, __res, type, Type) \ 465#define free_resource(_res, __res, type, Type) \
510 do { \ 466 do { \
511 int i; \
512 if (!(_res)->type##s) \ 467 if (!(_res)->type##s) \
513 break; \ 468 break; \
514 for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 469 for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
@@ -521,7 +476,6 @@ static void free_resources(struct resources *res)
521 476
522#define free_properties(_res, __res, type) \ 477#define free_properties(_res, __res, type) \
523 do { \ 478 do { \
524 int i; \
525 for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 479 for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
526 drmModeFreeObjectProperties(res->type##s[i].props); \ 480 drmModeFreeObjectProperties(res->type##s[i].props); \
527 free(res->type##s[i].props_info); \ 481 free(res->type##s[i].props_info); \
@@ -533,6 +487,10 @@ static void free_resources(struct resources *res)
533 487
534 free_resource(res, res, crtc, Crtc); 488 free_resource(res, res, crtc, Crtc);
535 free_resource(res, res, encoder, Encoder); 489 free_resource(res, res, encoder, Encoder);
490
491 for (i = 0; i < res->res->count_connectors; i++)
492 free(res->connectors[i].name);
493
536 free_resource(res, res, connector, Connector); 494 free_resource(res, res, connector, Connector);
537 free_resource(res, res, fb, FB); 495 free_resource(res, res, fb, FB);
538 496
@@ -555,12 +513,10 @@ static struct resources *get_resources(struct device *dev)
555 struct resources *res; 513 struct resources *res;
556 int i; 514 int i;
557 515
558 res = malloc(sizeof *res); 516 res = calloc(1, sizeof(*res));
559 if (res == 0) 517 if (res == 0)
560 return NULL; 518 return NULL;
561 519
562 memset(res, 0, sizeof *res);
563
564 drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); 520 drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
565 drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1); 521 drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1);
566 522
@@ -571,22 +527,16 @@ static struct resources *get_resources(struct device *dev)
571 goto error; 527 goto error;
572 } 528 }
573 529
574 res->crtcs = malloc(res->res->count_crtcs * sizeof *res->crtcs); 530 res->crtcs = calloc(res->res->count_crtcs, sizeof(*res->crtcs));
575 res->encoders = malloc(res->res->count_encoders * sizeof *res->encoders); 531 res->encoders = calloc(res->res->count_encoders, sizeof(*res->encoders));
576 res->connectors = malloc(res->res->count_connectors * sizeof *res->connectors); 532 res->connectors = calloc(res->res->count_connectors, sizeof(*res->connectors));
577 res->fbs = malloc(res->res->count_fbs * sizeof *res->fbs); 533 res->fbs = calloc(res->res->count_fbs, sizeof(*res->fbs));
578 534
579 if (!res->crtcs || !res->encoders || !res->connectors || !res->fbs) 535 if (!res->crtcs || !res->encoders || !res->connectors || !res->fbs)
580 goto error; 536 goto error;
581 537
582 memset(res->crtcs , 0, res->res->count_crtcs * sizeof *res->crtcs);
583 memset(res->encoders, 0, res->res->count_encoders * sizeof *res->encoders);
584 memset(res->connectors, 0, res->res->count_connectors * sizeof *res->connectors);
585 memset(res->fbs, 0, res->res->count_fbs * sizeof *res->fbs);
586
587#define get_resource(_res, __res, type, Type) \ 538#define get_resource(_res, __res, type, Type) \
588 do { \ 539 do { \
589 int i; \
590 for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 540 for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
591 (_res)->type##s[i].type = \ 541 (_res)->type##s[i].type = \
592 drmModeGet##Type(dev->fd, (_res)->__res->type##s[i]); \ 542 drmModeGet##Type(dev->fd, (_res)->__res->type##s[i]); \
@@ -602,9 +552,18 @@ static struct resources *get_resources(struct device *dev)
602 get_resource(res, res, connector, Connector); 552 get_resource(res, res, connector, Connector);
603 get_resource(res, res, fb, FB); 553 get_resource(res, res, fb, FB);
604 554
555 /* Set the name of all connectors based on the type name and the per-type ID. */
556 for (i = 0; i < res->res->count_connectors; i++) {
557 struct connector *connector = &res->connectors[i];
558 drmModeConnector *conn = connector->connector;
559
560 asprintf(&connector->name, "%s-%u",
561 util_lookup_connector_type_name(conn->connector_type),
562 conn->connector_type_id);
563 }
564
605#define get_properties(_res, __res, type, Type) \ 565#define get_properties(_res, __res, type, Type) \
606 do { \ 566 do { \
607 int i; \
608 for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ 567 for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
609 struct type *obj = &res->type##s[i]; \ 568 struct type *obj = &res->type##s[i]; \
610 unsigned int j; \ 569 unsigned int j; \
@@ -618,8 +577,8 @@ static struct resources *get_resources(struct device *dev)
618 strerror(errno)); \ 577 strerror(errno)); \
619 continue; \ 578 continue; \
620 } \ 579 } \
621 obj->props_info = malloc(obj->props->count_props * \ 580 obj->props_info = calloc(obj->props->count_props, \
622 sizeof *obj->props_info); \ 581 sizeof(*obj->props_info)); \
623 if (!obj->props_info) \ 582 if (!obj->props_info) \
624 continue; \ 583 continue; \
625 for (j = 0; j < obj->props->count_props; ++j) \ 584 for (j = 0; j < obj->props->count_props; ++j) \
@@ -641,12 +600,10 @@ static struct resources *get_resources(struct device *dev)
641 return res; 600 return res;
642 } 601 }
643 602
644 res->planes = malloc(res->plane_res->count_planes * sizeof *res->planes); 603 res->planes = calloc(res->plane_res->count_planes, sizeof(*res->planes));
645 if (!res->planes) 604 if (!res->planes)
646 goto error; 605 goto error;
647 606
648 memset(res->planes, 0, res->plane_res->count_planes * sizeof *res->planes);
649
650 get_resource(res, plane_res, plane, Plane); 607 get_resource(res, plane_res, plane, Plane);
651 get_properties(res, plane_res, plane, PLANE); 608 get_properties(res, plane_res, plane, PLANE);
652 609
@@ -670,6 +627,21 @@ static int get_crtc_index(struct device *dev, uint32_t id)
670 return -1; 627 return -1;
671} 628}
672 629
630static drmModeConnector *get_connector_by_name(struct device *dev, const char *name)
631{
632 struct connector *connector;
633 int i;
634
635 for (i = 0; i < dev->resources->res->count_connectors; i++) {
636 connector = &dev->resources->connectors[i];
637
638 if (strcmp(connector->name, name) == 0)
639 return connector->connector;
640 }
641
642 return NULL;
643}
644
673static drmModeConnector *get_connector_by_id(struct device *dev, uint32_t id) 645static drmModeConnector *get_connector_by_id(struct device *dev, uint32_t id)
674{ 646{
675 drmModeConnector *connector; 647 drmModeConnector *connector;
@@ -710,6 +682,7 @@ static drmModeEncoder *get_encoder_by_id(struct device *dev, uint32_t id)
710 * can bind it with a free crtc. 682 * can bind it with a free crtc.
711 */ 683 */
712struct pipe_arg { 684struct pipe_arg {
685 const char **cons;
713 uint32_t *con_ids; 686 uint32_t *con_ids;
714 unsigned int num_cons; 687 unsigned int num_cons;
715 uint32_t crtc_id; 688 uint32_t crtc_id;
@@ -732,6 +705,7 @@ struct plane_arg {
732 uint32_t w, h; 705 uint32_t w, h;
733 double scale; 706 double scale;
734 unsigned int fb_id; 707 unsigned int fb_id;
708 struct bo *bo;
735 char format_str[5]; /* need to leave room for terminating \0 */ 709 char format_str[5]; /* need to leave room for terminating \0 */
736 unsigned int fourcc; 710 unsigned int fourcc;
737}; 711};
@@ -824,8 +798,8 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe)
824 pipe->mode_str, pipe->vrefresh); 798 pipe->mode_str, pipe->vrefresh);
825 if (mode == NULL) { 799 if (mode == NULL) {
826 fprintf(stderr, 800 fprintf(stderr,
827 "failed to find mode \"%s\" for connector %u\n", 801 "failed to find mode \"%s\" for connector %s\n",
828 pipe->mode_str, pipe->con_ids[i]); 802 pipe->mode_str, pipe->cons[i]);
829 return -EINVAL; 803 return -EINVAL;
830 } 804 }
831 } 805 }
@@ -963,10 +937,22 @@ page_flip_handler(int fd, unsigned int frame,
963 } 937 }
964} 938}
965 939
940static bool format_support(const drmModePlanePtr ovr, uint32_t fmt)
941{
942 unsigned int i;
943
944 for (i = 0; i < ovr->count_formats; ++i) {
945 if (ovr->formats[i] == fmt)
946 return true;
947 }
948
949 return false;
950}
951
966static int set_plane(struct device *dev, struct plane_arg *p) 952static int set_plane(struct device *dev, struct plane_arg *p)
967{ 953{
968 drmModePlane *ovr; 954 drmModePlane *ovr;
969 uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ 955 uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
970 uint32_t plane_id = 0; 956 uint32_t plane_id = 0;
971 struct bo *plane_bo; 957 struct bo *plane_bo;
972 uint32_t plane_flags = 0; 958 uint32_t plane_flags = 0;
@@ -993,7 +979,7 @@ static int set_plane(struct device *dev, struct plane_arg *p)
993 979
994 for (i = 0; i < dev->resources->plane_res->count_planes && !plane_id; i++) { 980 for (i = 0; i < dev->resources->plane_res->count_planes && !plane_id; i++) {
995 ovr = dev->resources->planes[i].plane; 981 ovr = dev->resources->planes[i].plane;
996 if (!ovr) 982 if (!ovr || !format_support(ovr, p->fourcc))
997 continue; 983 continue;
998 984
999 if ((ovr->possible_crtcs & (1 << pipe)) && !ovr->crtc_id) 985 if ((ovr->possible_crtcs & (1 << pipe)) && !ovr->crtc_id)
@@ -1010,10 +996,12 @@ static int set_plane(struct device *dev, struct plane_arg *p)
1010 p->w, p->h, p->format_str, plane_id); 996 p->w, p->h, p->format_str, plane_id);
1011 997
1012 plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, handles, 998 plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, handles,
1013 pitches, offsets, PATTERN_TILES); 999 pitches, offsets, UTIL_PATTERN_TILES);
1014 if (plane_bo == NULL) 1000 if (plane_bo == NULL)
1015 return -1; 1001 return -1;
1016 1002
1003 p->bo = plane_bo;
1004
1017 /* just use single plane format for now.. */ 1005 /* just use single plane format for now.. */
1018 if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc, 1006 if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc,
1019 handles, pitches, offsets, &p->fb_id, plane_flags)) { 1007 handles, pitches, offsets, &p->fb_id, plane_flags)) {
@@ -1046,9 +1034,22 @@ static int set_plane(struct device *dev, struct plane_arg *p)
1046 return 0; 1034 return 0;
1047} 1035}
1048 1036
1037static void clear_planes(struct device *dev, struct plane_arg *p, unsigned int count)
1038{
1039 unsigned int i;
1040
1041 for (i = 0; i < count; i++) {
1042 if (p[i].fb_id)
1043 drmModeRmFB(dev->fd, p[i].fb_id);
1044 if (p[i].bo)
1045 bo_destroy(p[i].bo);
1046 }
1047}
1048
1049
1049static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) 1050static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
1050{ 1051{
1051 uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ 1052 uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
1052 unsigned int fb_id; 1053 unsigned int fb_id;
1053 struct bo *bo; 1054 struct bo *bo;
1054 unsigned int i; 1055 unsigned int i;
@@ -1057,6 +1058,7 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
1057 1058
1058 dev->mode.width = 0; 1059 dev->mode.width = 0;
1059 dev->mode.height = 0; 1060 dev->mode.height = 0;
1061 dev->mode.fb_id = 0;
1060 1062
1061 for (i = 0; i < count; i++) { 1063 for (i = 0; i < count; i++) {
1062 struct pipe_arg *pipe = &pipes[i]; 1064 struct pipe_arg *pipe = &pipes[i];
@@ -1070,11 +1072,14 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
1070 dev->mode.height = pipe->mode->vdisplay; 1072 dev->mode.height = pipe->mode->vdisplay;
1071 } 1073 }
1072 1074
1073 bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width, dev->mode.height, 1075 bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width,
1074 handles, pitches, offsets, PATTERN_SMPTE); 1076 dev->mode.height, handles, pitches, offsets,
1077 UTIL_PATTERN_SMPTE);
1075 if (bo == NULL) 1078 if (bo == NULL)
1076 return; 1079 return;
1077 1080
1081 dev->mode.bo = bo;
1082
1078 ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height, 1083 ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height,
1079 pipes[0].fourcc, handles, pitches, offsets, &fb_id, 0); 1084 pipes[0].fourcc, handles, pitches, offsets, &fb_id, 0);
1080 if (ret) { 1085 if (ret) {
@@ -1083,6 +1088,8 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
1083 return; 1088 return;
1084 } 1089 }
1085 1090
1091 dev->mode.fb_id = fb_id;
1092
1086 x = 0; 1093 x = 0;
1087 for (i = 0; i < count; i++) { 1094 for (i = 0; i < count; i++) {
1088 struct pipe_arg *pipe = &pipes[i]; 1095 struct pipe_arg *pipe = &pipes[i];
@@ -1093,7 +1100,7 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
1093 printf("setting mode %s-%dHz@%s on connectors ", 1100 printf("setting mode %s-%dHz@%s on connectors ",
1094 pipe->mode_str, pipe->mode->vrefresh, pipe->format_str); 1101 pipe->mode_str, pipe->mode->vrefresh, pipe->format_str);
1095 for (j = 0; j < pipe->num_cons; ++j) 1102 for (j = 0; j < pipe->num_cons; ++j)
1096 printf("%u, ", pipe->con_ids[j]); 1103 printf("%s, ", pipe->cons[j]);
1097 printf("crtc %d\n", pipe->crtc->crtc->crtc_id); 1104 printf("crtc %d\n", pipe->crtc->crtc->crtc_id);
1098 1105
1099 ret = drmModeSetCrtc(dev->fd, pipe->crtc->crtc->crtc_id, fb_id, 1106 ret = drmModeSetCrtc(dev->fd, pipe->crtc->crtc->crtc_id, fb_id,
@@ -1110,9 +1117,14 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
1110 return; 1117 return;
1111 } 1118 }
1112 } 1119 }
1120}
1113 1121
1114 dev->mode.bo = bo; 1122static void clear_mode(struct device *dev)
1115 dev->mode.fb_id = fb_id; 1123{
1124 if (dev->mode.fb_id)
1125 drmModeRmFB(dev->fd, dev->mode.fb_id);
1126 if (dev->mode.bo)
1127 bo_destroy(dev->mode.bo);
1116} 1128}
1117 1129
1118static void set_planes(struct device *dev, struct plane_arg *p, unsigned int count) 1130static void set_planes(struct device *dev, struct plane_arg *p, unsigned int count)
@@ -1127,7 +1139,7 @@ static void set_planes(struct device *dev, struct plane_arg *p, unsigned int cou
1127 1139
1128static void set_cursors(struct device *dev, struct pipe_arg *pipes, unsigned int count) 1140static void set_cursors(struct device *dev, struct pipe_arg *pipes, unsigned int count)
1129{ 1141{
1130 uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ 1142 uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
1131 struct bo *bo; 1143 struct bo *bo;
1132 unsigned int i; 1144 unsigned int i;
1133 int ret; 1145 int ret;
@@ -1140,10 +1152,12 @@ static void set_cursors(struct device *dev, struct pipe_arg *pipes, unsigned int
1140 * translucent alpha 1152 * translucent alpha
1141 */ 1153 */
1142 bo = bo_create(dev->fd, DRM_FORMAT_ARGB8888, cw, ch, handles, pitches, 1154 bo = bo_create(dev->fd, DRM_FORMAT_ARGB8888, cw, ch, handles, pitches,
1143 offsets, PATTERN_PLAIN); 1155 offsets, UTIL_PATTERN_PLAIN);
1144 if (bo == NULL) 1156 if (bo == NULL)
1145 return; 1157 return;
1146 1158
1159 dev->mode.cursor_bo = bo;
1160
1147 for (i = 0; i < count; i++) { 1161 for (i = 0; i < count; i++) {
1148 struct pipe_arg *pipe = &pipes[i]; 1162 struct pipe_arg *pipe = &pipes[i];
1149 ret = cursor_init(dev->fd, handles[0], 1163 ret = cursor_init(dev->fd, handles[0],
@@ -1163,20 +1177,23 @@ static void set_cursors(struct device *dev, struct pipe_arg *pipes, unsigned int
1163static void clear_cursors(struct device *dev) 1177static void clear_cursors(struct device *dev)
1164{ 1178{
1165 cursor_stop(); 1179 cursor_stop();
1180
1181 if (dev->mode.cursor_bo)
1182 bo_destroy(dev->mode.cursor_bo);
1166} 1183}
1167 1184
1168static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned int count) 1185static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned int count)
1169{ 1186{
1170 uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ 1187 uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
1171 unsigned int other_fb_id; 1188 unsigned int other_fb_id;
1172 struct bo *other_bo; 1189 struct bo *other_bo;
1173 drmEventContext evctx; 1190 drmEventContext evctx;
1174 unsigned int i; 1191 unsigned int i;
1175 int ret; 1192 int ret;
1176 1193
1177 other_bo = bo_create(dev->fd, pipes[0].fourcc, 1194 other_bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width,
1178 dev->mode.width, dev->mode.height, 1195 dev->mode.height, handles, pitches, offsets,
1179 handles, pitches, offsets, PATTERN_PLAIN); 1196 UTIL_PATTERN_PLAIN);
1180 if (other_bo == NULL) 1197 if (other_bo == NULL)
1181 return; 1198 return;
1182 1199
@@ -1185,7 +1202,7 @@ static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned
1185 &other_fb_id, 0); 1202 &other_fb_id, 0);
1186 if (ret) { 1203 if (ret) {
1187 fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); 1204 fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
1188 return; 1205 goto err;
1189 } 1206 }
1190 1207
1191 for (i = 0; i < count; i++) { 1208 for (i = 0; i < count; i++) {
@@ -1199,7 +1216,7 @@ static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned
1199 pipe); 1216 pipe);
1200 if (ret) { 1217 if (ret) {
1201 fprintf(stderr, "failed to page flip: %s\n", strerror(errno)); 1218 fprintf(stderr, "failed to page flip: %s\n", strerror(errno));
1202 return; 1219 goto err_rmfb;
1203 } 1220 }
1204 gettimeofday(&pipe->start, NULL); 1221 gettimeofday(&pipe->start, NULL);
1205 pipe->swap_count = 0; 1222 pipe->swap_count = 0;
@@ -1212,7 +1229,7 @@ static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned
1212 evctx.version = DRM_EVENT_CONTEXT_VERSION; 1229 evctx.version = DRM_EVENT_CONTEXT_VERSION;
1213 evctx.vblank_handler = NULL; 1230 evctx.vblank_handler = NULL;
1214 evctx.page_flip_handler = page_flip_handler; 1231 evctx.page_flip_handler = page_flip_handler;
1215 1232
1216 while (1) { 1233 while (1) {
1217#if 0 1234#if 0
1218 struct pollfd pfd[2]; 1235 struct pollfd pfd[2];
@@ -1232,7 +1249,6 @@ static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned
1232#else 1249#else
1233 struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; 1250 struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
1234 fd_set fds; 1251 fd_set fds;
1235 int ret;
1236 1252
1237 FD_ZERO(&fds); 1253 FD_ZERO(&fds);
1238 FD_SET(0, &fds); 1254 FD_SET(0, &fds);
@@ -1251,6 +1267,9 @@ static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned
1251 drmHandleEvent(dev->fd, &evctx); 1267 drmHandleEvent(dev->fd, &evctx);
1252 } 1268 }
1253 1269
1270err_rmfb:
1271 drmModeRmFB(dev->fd, other_fb_id);
1272err:
1254 bo_destroy(other_bo); 1273 bo_destroy(other_bo);
1255} 1274}
1256 1275
@@ -1269,18 +1288,24 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
1269 1288
1270 /* Count the number of connectors and allocate them. */ 1289 /* Count the number of connectors and allocate them. */
1271 pipe->num_cons = 1; 1290 pipe->num_cons = 1;
1272 for (p = arg; isdigit(*p) || *p == ','; ++p) { 1291 for (p = arg; *p && *p != ':' && *p != '@'; ++p) {
1273 if (*p == ',') 1292 if (*p == ',')
1274 pipe->num_cons++; 1293 pipe->num_cons++;
1275 } 1294 }
1276 1295
1277 pipe->con_ids = malloc(pipe->num_cons * sizeof *pipe->con_ids); 1296 pipe->con_ids = calloc(pipe->num_cons, sizeof(*pipe->con_ids));
1278 if (pipe->con_ids == NULL) 1297 pipe->cons = calloc(pipe->num_cons, sizeof(*pipe->cons));
1298 if (pipe->con_ids == NULL || pipe->cons == NULL)
1279 return -1; 1299 return -1;
1280 1300
1281 /* Parse the connectors. */ 1301 /* Parse the connectors. */
1282 for (i = 0, p = arg; i < pipe->num_cons; ++i, p = endp + 1) { 1302 for (i = 0, p = arg; i < pipe->num_cons; ++i, p = endp + 1) {
1283 pipe->con_ids[i] = strtoul(p, &endp, 10); 1303 endp = strpbrk(p, ",@:");
1304 if (!endp)
1305 break;
1306
1307 pipe->cons[i] = strndup(p, endp - p);
1308
1284 if (*endp != ',') 1309 if (*endp != ',')
1285 break; 1310 break;
1286 } 1311 }
@@ -1316,7 +1341,7 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
1316 pipe->format_str[4] = '\0'; 1341 pipe->format_str[4] = '\0';
1317 } 1342 }
1318 1343
1319 pipe->fourcc = format_fourcc(pipe->format_str); 1344 pipe->fourcc = util_format_fourcc(pipe->format_str);
1320 if (pipe->fourcc == 0) { 1345 if (pipe->fourcc == 0) {
1321 fprintf(stderr, "unknown format %s\n", pipe->format_str); 1346 fprintf(stderr, "unknown format %s\n", pipe->format_str);
1322 return -1; 1347 return -1;
@@ -1329,8 +1354,6 @@ static int parse_plane(struct plane_arg *plane, const char *p)
1329{ 1354{
1330 char *end; 1355 char *end;
1331 1356
1332 memset(plane, 0, sizeof *plane);
1333
1334 plane->crtc_id = strtoul(p, &end, 10); 1357 plane->crtc_id = strtoul(p, &end, 10);
1335 if (*end != ':') 1358 if (*end != ':')
1336 return -EINVAL; 1359 return -EINVAL;
@@ -1371,7 +1394,7 @@ static int parse_plane(struct plane_arg *plane, const char *p)
1371 strcpy(plane->format_str, "XR24"); 1394 strcpy(plane->format_str, "XR24");
1372 } 1395 }
1373 1396
1374 plane->fourcc = format_fourcc(plane->format_str); 1397 plane->fourcc = util_format_fourcc(plane->format_str);
1375 if (plane->fourcc == 0) { 1398 if (plane->fourcc == 0) {
1376 fprintf(stderr, "unknown format %s\n", plane->format_str); 1399 fprintf(stderr, "unknown format %s\n", plane->format_str);
1377 return -EINVAL; 1400 return -EINVAL;
@@ -1444,6 +1467,32 @@ static int cursor_supported(void)
1444 return 1; 1467 return 1;
1445} 1468}
1446 1469
1470static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
1471{
1472 drmModeConnector *connector;
1473 unsigned int i;
1474 uint32_t id;
1475 char *endp;
1476
1477 for (i = 0; i < pipe->num_cons; i++) {
1478 id = strtoul(pipe->cons[i], &endp, 10);
1479 if (endp == pipe->cons[i]) {
1480 connector = get_connector_by_name(dev, pipe->cons[i]);
1481 if (!connector) {
1482 fprintf(stderr, "no connector named '%s'\n",
1483 pipe->cons[i]);
1484 return -ENODEV;
1485 }
1486
1487 id = connector->connector_id;
1488 }
1489
1490 pipe->con_ids[i] = id;
1491 }
1492
1493 return 0;
1494}
1495
1447static char optstr[] = "cdD:efM:P:ps:Cvw:"; 1496static char optstr[] = "cdD:efM:P:ps:Cvw:";
1448 1497
1449int main(int argc, char **argv) 1498int main(int argc, char **argv)
@@ -1455,11 +1504,10 @@ int main(int argc, char **argv)
1455 int drop_master = 0; 1504 int drop_master = 0;
1456 int test_vsync = 0; 1505 int test_vsync = 0;
1457 int test_cursor = 0; 1506 int test_cursor = 0;
1458 const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tilcdc", "msm", "sti", "tegra" };
1459 char *device = NULL; 1507 char *device = NULL;
1460 char *module = NULL; 1508 char *module = NULL;
1461 unsigned int i; 1509 unsigned int i;
1462 int count = 0, plane_count = 0; 1510 unsigned int count = 0, plane_count = 0;
1463 unsigned int prop_count = 0; 1511 unsigned int prop_count = 0;
1464 struct pipe_arg *pipe_args = NULL; 1512 struct pipe_arg *pipe_args = NULL;
1465 struct plane_arg *plane_args = NULL; 1513 struct plane_arg *plane_args = NULL;
@@ -1502,6 +1550,7 @@ int main(int argc, char **argv)
1502 fprintf(stderr, "memory allocation failed\n"); 1550 fprintf(stderr, "memory allocation failed\n");
1503 return 1; 1551 return 1;
1504 } 1552 }
1553 memset(&plane_args[plane_count], 0, sizeof(*plane_args));
1505 1554
1506 if (parse_plane(&plane_args[plane_count], optarg) < 0) 1555 if (parse_plane(&plane_args[plane_count], optarg) < 0)
1507 usage(argv[0]); 1556 usage(argv[0]);
@@ -1519,11 +1568,12 @@ int main(int argc, char **argv)
1519 fprintf(stderr, "memory allocation failed\n"); 1568 fprintf(stderr, "memory allocation failed\n");
1520 return 1; 1569 return 1;
1521 } 1570 }
1571 memset(&pipe_args[count], 0, sizeof(*pipe_args));
1522 1572
1523 if (parse_connector(&pipe_args[count], optarg) < 0) 1573 if (parse_connector(&pipe_args[count], optarg) < 0)
1524 usage(argv[0]); 1574 usage(argv[0]);
1525 1575
1526 count++; 1576 count++;
1527 break; 1577 break;
1528 case 'C': 1578 case 'C':
1529 test_cursor = 1; 1579 test_cursor = 1;
@@ -1538,6 +1588,7 @@ int main(int argc, char **argv)
1538 fprintf(stderr, "memory allocation failed\n"); 1588 fprintf(stderr, "memory allocation failed\n");
1539 return 1; 1589 return 1;
1540 } 1590 }
1591 memset(&prop_args[prop_count], 0, sizeof(*prop_args));
1541 1592
1542 if (parse_property(&prop_args[prop_count], optarg) < 0) 1593 if (parse_property(&prop_args[prop_count], optarg) < 0)
1543 usage(argv[0]); 1594 usage(argv[0]);
@@ -1553,29 +1604,9 @@ int main(int argc, char **argv)
1553 if (!args) 1604 if (!args)
1554 encoders = connectors = crtcs = planes = framebuffers = 1; 1605 encoders = connectors = crtcs = planes = framebuffers = 1;
1555 1606
1556 if (module) { 1607 dev.fd = util_open(module, device);
1557 dev.fd = drmOpen(module, device); 1608 if (dev.fd < 0)
1558 if (dev.fd < 0) { 1609 return -1;
1559 fprintf(stderr, "failed to open device '%s'.\n", module);
1560 return 1;
1561 }
1562 } else {
1563 for (i = 0; i < ARRAY_SIZE(modules); i++) {
1564 printf("trying to open device '%s'...", modules[i]);
1565 dev.fd = drmOpen(modules[i], device);
1566 if (dev.fd < 0) {
1567 printf("failed.\n");
1568 } else {
1569 printf("success.\n");
1570 break;
1571 }
1572 }
1573
1574 if (dev.fd < 0) {
1575 fprintf(stderr, "no device found.\n");
1576 return 1;
1577 }
1578 }
1579 1610
1580 if (test_vsync && !page_flipping_supported()) { 1611 if (test_vsync && !page_flipping_supported()) {
1581 fprintf(stderr, "page flipping not supported by drm.\n"); 1612 fprintf(stderr, "page flipping not supported by drm.\n");
@@ -1598,6 +1629,14 @@ int main(int argc, char **argv)
1598 return 1; 1629 return 1;
1599 } 1630 }
1600 1631
1632 for (i = 0; i < count; i++) {
1633 if (pipe_resolve_connectors(&dev, &pipe_args[i]) < 0) {
1634 free_resources(dev.resources);
1635 drmClose(dev.fd);
1636 return 1;
1637 }
1638 }
1639
1601#define dump_resource(dev, res) if (res) dump_##res(dev) 1640#define dump_resource(dev, res) if (res) dump_##res(dev)
1602 1641
1603 dump_resource(&dev, encoders); 1642 dump_resource(&dev, encoders);
@@ -1638,7 +1677,11 @@ int main(int argc, char **argv)
1638 if (test_cursor) 1677 if (test_cursor)
1639 clear_cursors(&dev); 1678 clear_cursors(&dev);
1640 1679
1641 bo_destroy(dev.mode.bo); 1680 if (plane_count)
1681 clear_planes(&dev, plane_args, plane_count);
1682
1683 if (count)
1684 clear_mode(&dev);
1642 } 1685 }
1643 1686
1644 free_resources(dev.resources); 1687 free_resources(dev.resources);
diff --git a/tests/name_from_fd.c b/tests/name_from_fd.c
index 330c8ff0..52646812 100644
--- a/tests/name_from_fd.c
+++ b/tests/name_from_fd.c
@@ -28,6 +28,7 @@
28#include <unistd.h> 28#include <unistd.h>
29#include <fcntl.h> 29#include <fcntl.h>
30#include <limits.h> 30#include <limits.h>
31#include <string.h>
31#include "drmtest.h" 32#include "drmtest.h"
32 33
33/** 34/**
@@ -39,13 +40,12 @@
39 */ 40 */
40int main(int argc, char **argv) 41int main(int argc, char **argv)
41{ 42{
42 int fd, ret; 43 int fd;
43 drm_set_version_t sv, version;
44 const char *name = "/dev/dri/card0"; 44 const char *name = "/dev/dri/card0";
45 char *v; 45 char *v;
46 46
47 fd = open("/dev/dri/card0", O_RDWR); 47 fd = open("/dev/dri/card0", O_RDWR);
48 if (fd == -1) 48 if (fd < 0)
49 return 0; 49 return 0;
50 50
51 v = drmGetDeviceNameFromFd(fd); 51 v = drmGetDeviceNameFromFd(fd);
diff --git a/tests/nouveau/.gitignore b/tests/nouveau/.gitignore
new file mode 100644
index 00000000..837bfb91
--- /dev/null
+++ b/tests/nouveau/.gitignore
@@ -0,0 +1 @@
threaded
diff --git a/tests/nouveau/Makefile.am b/tests/nouveau/Makefile.am
new file mode 100644
index 00000000..c4f6e299
--- /dev/null
+++ b/tests/nouveau/Makefile.am
@@ -0,0 +1,16 @@
1AM_CPPFLAGS = \
2 -I$(top_srcdir)/include/drm \
3 -I$(top_srcdir)/nouveau \
4 -I$(top_srcdir)
5
6AM_CFLAGS = $(WARN_CFLAGS)
7
8LDADD = \
9 ../../nouveau/libdrm_nouveau.la \
10 ../../libdrm.la \
11 -ldl -lpthread
12
13TESTS = threaded
14
15check_PROGRAMS = $(TESTS)
16
diff --git a/tests/nouveau/threaded.c b/tests/nouveau/threaded.c
new file mode 100644
index 00000000..281af460
--- /dev/null
+++ b/tests/nouveau/threaded.c
@@ -0,0 +1,156 @@
1/*
2 * Copyright © 2015 Canonical Ltd. (Maarten Lankhorst)
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#ifdef HAVE_CONFIG_H
24# include "config.h"
25#endif
26
27#include <sys/ioctl.h>
28#include <dlfcn.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <unistd.h>
32#include <errno.h>
33#include <pthread.h>
34
35#include "xf86drm.h"
36#include "nouveau.h"
37
38static typeof(ioctl) *old_ioctl;
39static int failed;
40
41static int import_fd;
42
43int ioctl(int fd, unsigned long request, ...)
44{
45 va_list va;
46 int ret;
47 void *arg;
48
49 va_start(va, request);
50 arg = va_arg(va, void *);
51 ret = old_ioctl(fd, request, arg);
52 va_end(va);
53
54 if (ret < 0 && request == DRM_IOCTL_GEM_CLOSE && errno == EINVAL)
55 failed = 1;
56
57 return ret;
58}
59
60static void *
61openclose(void *dev)
62{
63 struct nouveau_device *nvdev = dev;
64 struct nouveau_bo *bo = NULL;
65 int i;
66
67 for (i = 0; i < 100000; ++i) {
68 if (!nouveau_bo_prime_handle_ref(nvdev, import_fd, &bo))
69 nouveau_bo_ref(NULL, &bo);
70 }
71 return NULL;
72}
73
74int main(int argc, char *argv[])
75{
76 drmVersionPtr version;
77 const char *device = NULL;
78 int err, fd, fd2;
79 struct nouveau_device *nvdev, *nvdev2;
80 struct nouveau_bo *bo;
81 pthread_t t1, t2;
82
83 old_ioctl = dlsym(RTLD_NEXT, "ioctl");
84
85 if (argc < 2) {
86 fd = drmOpenWithType("nouveau", NULL, DRM_NODE_RENDER);
87 if (fd >= 0)
88 fd2 = drmOpenWithType("nouveau", NULL, DRM_NODE_RENDER);
89 } else {
90 device = argv[1];
91
92 fd = open(device, O_RDWR);
93 if (fd >= 0)
94 fd2 = open(device, O_RDWR);
95 else
96 fd2 = fd = -errno;
97 }
98
99 if (fd < 0) {
100 fprintf(stderr, "Opening nouveau render node failed with %i\n", fd);
101 return device ? -fd : 77;
102 }
103
104 if (fd2 < 0) {
105 fprintf(stderr, "Opening second nouveau render node failed with %i\n", -errno);
106 return errno;
107 }
108
109 version = drmGetVersion(fd);
110 if (version) {
111 printf("Version: %d.%d.%d\n", version->version_major,
112 version->version_minor, version->version_patchlevel);
113 printf(" Name: %s\n", version->name);
114 printf(" Date: %s\n", version->date);
115 printf(" Description: %s\n", version->desc);
116
117 drmFreeVersion(version);
118 }
119
120 err = nouveau_device_wrap(fd, 0, &nvdev);
121 if (!err)
122 err = nouveau_device_wrap(fd2, 0, &nvdev2);
123 if (err < 0)
124 return 1;
125
126 err = nouveau_bo_new(nvdev2, NOUVEAU_BO_GART, 0, 4096, NULL, &bo);
127 if (!err)
128 err = nouveau_bo_set_prime(bo, &import_fd);
129
130 if (!err) {
131 pthread_create(&t1, NULL, openclose, nvdev);
132 pthread_create(&t2, NULL, openclose, nvdev);
133 }
134
135 pthread_join(t1, NULL);
136 pthread_join(t2, NULL);
137
138 close(import_fd);
139 nouveau_bo_ref(NULL, &bo);
140
141 nouveau_device_del(&nvdev2);
142 nouveau_device_del(&nvdev);
143 if (device) {
144 close(fd2);
145 close(fd);
146 } else {
147 drmClose(fd2);
148 drmClose(fd);
149 }
150
151 if (failed)
152 fprintf(stderr, "DRM_IOCTL_GEM_CLOSE failed with EINVAL,\n"
153 "race in opening/closing bo is likely.\n");
154
155 return failed;
156}
diff --git a/tests/proptest/Android.mk b/tests/proptest/Android.mk
new file mode 100644
index 00000000..d0ab5c92
--- /dev/null
+++ b/tests/proptest/Android.mk
@@ -0,0 +1,13 @@
1LOCAL_PATH := $(call my-dir)
2
3include $(CLEAR_VARS)
4include $(LOCAL_PATH)/Makefile.sources
5
6LOCAL_SRC_FILES := $(PROPTEST_FILES)
7
8LOCAL_MODULE := proptest
9
10LOCAL_SHARED_LIBRARIES := libdrm
11LOCAL_STATIC_LIBRARIES := libdrm_util
12
13include $(BUILD_EXECUTABLE)
diff --git a/tests/proptest/Makefile.am b/tests/proptest/Makefile.am
index f81a3c00..3fde46be 100644
--- a/tests/proptest/Makefile.am
+++ b/tests/proptest/Makefile.am
@@ -1,11 +1,21 @@
1include Makefile.sources
2
1AM_CFLAGS = \ 3AM_CFLAGS = \
4 $(WARN_CFLAGS)\
2 -I$(top_srcdir)/include/drm \ 5 -I$(top_srcdir)/include/drm \
6 -I$(top_srcdir)/tests \
3 -I$(top_srcdir) 7 -I$(top_srcdir)
4 8
9if HAVE_INSTALL_TESTS
10bin_PROGRAMS = \
11 proptest
12else
5noinst_PROGRAMS = \ 13noinst_PROGRAMS = \
6 proptest 14 proptest
15endif
16
17proptest_SOURCES = $(PROPTEST_FILES)
7 18
8proptest_SOURCES = \
9 proptest.c
10proptest_LDADD = \ 19proptest_LDADD = \
11 $(top_builddir)/libdrm.la 20 $(top_builddir)/libdrm.la \
21 $(top_builddir)/tests/util/libutil.la
diff --git a/tests/proptest/Makefile.sources b/tests/proptest/Makefile.sources
new file mode 100644
index 00000000..446110d6
--- /dev/null
+++ b/tests/proptest/Makefile.sources
@@ -0,0 +1,2 @@
1PROPTEST_FILES := \
2 proptest.c
diff --git a/tests/proptest/proptest.c b/tests/proptest/proptest.c
index 7618f63d..24c63456 100644
--- a/tests/proptest/proptest.c
+++ b/tests/proptest/proptest.c
@@ -27,6 +27,7 @@
27 27
28#include <assert.h> 28#include <assert.h>
29#include <errno.h> 29#include <errno.h>
30#include <getopt.h>
30#include <inttypes.h> 31#include <inttypes.h>
31#include <stdlib.h> 32#include <stdlib.h>
32#include <stdio.h> 33#include <stdio.h>
@@ -35,7 +36,9 @@
35#include "xf86drm.h" 36#include "xf86drm.h"
36#include "xf86drmMode.h" 37#include "xf86drmMode.h"
37 38
38#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 39#include "util/common.h"
40#include "util/kms.h"
41
39static inline int64_t U642I64(uint64_t val) 42static inline int64_t U642I64(uint64_t val)
40{ 43{
41 return (int64_t)*((int64_t *)&val); 44 return (int64_t)*((int64_t *)&val);
@@ -44,44 +47,6 @@ static inline int64_t U642I64(uint64_t val)
44int fd; 47int fd;
45drmModeResPtr res = NULL; 48drmModeResPtr res = NULL;
46 49
47const char *connector_type_str(uint32_t type)
48{
49 switch (type) {
50 case DRM_MODE_CONNECTOR_Unknown:
51 return "Unknown";
52 case DRM_MODE_CONNECTOR_VGA:
53 return "VGA";
54 case DRM_MODE_CONNECTOR_DVII:
55 return "DVI-I";
56 case DRM_MODE_CONNECTOR_DVID:
57 return "DVI-D";
58 case DRM_MODE_CONNECTOR_DVIA:
59 return "DVI-A";
60 case DRM_MODE_CONNECTOR_Composite:
61 return "Composite";
62 case DRM_MODE_CONNECTOR_SVIDEO:
63 return "SVIDEO";
64 case DRM_MODE_CONNECTOR_LVDS:
65 return "LVDS";
66 case DRM_MODE_CONNECTOR_Component:
67 return "Component";
68 case DRM_MODE_CONNECTOR_9PinDIN:
69 return "9PinDin";
70 case DRM_MODE_CONNECTOR_DisplayPort:
71 return "DisplayPort";
72 case DRM_MODE_CONNECTOR_HDMIA:
73 return "HDMI-A";
74 case DRM_MODE_CONNECTOR_HDMIB:
75 return "HDMI-B";
76 case DRM_MODE_CONNECTOR_TV:
77 return "TV";
78 case DRM_MODE_CONNECTOR_eDP:
79 return "eDP";
80 default:
81 return "Invalid";
82 }
83}
84
85/* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */ 50/* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */
86static void 51static void
87dump_blob(uint32_t blob_id) 52dump_blob(uint32_t blob_id)
@@ -225,7 +190,7 @@ static void listConnectorProperties(void)
225 } 190 }
226 191
227 printf("Connector %u (%s-%u)\n", c->connector_id, 192 printf("Connector %u (%s-%u)\n", c->connector_id,
228 connector_type_str(c->connector_type), 193 util_lookup_connector_type_name(c->connector_type),
229 c->connector_type_id); 194 c->connector_type_id);
230 195
231 listObjectProperties(c->connector_id, 196 listObjectProperties(c->connector_id,
@@ -268,28 +233,32 @@ static int setProperty(char *argv[])
268 uint32_t obj_id, obj_type, prop_id; 233 uint32_t obj_id, obj_type, prop_id;
269 uint64_t value; 234 uint64_t value;
270 235
271 obj_id = atoi(argv[1]); 236 obj_id = atoi(argv[0]);
272 237
273 if (!strcmp(argv[2], "connector")) { 238 if (!strcmp(argv[1], "connector")) {
274 obj_type = DRM_MODE_OBJECT_CONNECTOR; 239 obj_type = DRM_MODE_OBJECT_CONNECTOR;
275 } else if (!strcmp(argv[2], "crtc")) { 240 } else if (!strcmp(argv[1], "crtc")) {
276 obj_type = DRM_MODE_OBJECT_CRTC; 241 obj_type = DRM_MODE_OBJECT_CRTC;
277 } else { 242 } else {
278 fprintf(stderr, "Invalid object type.\n"); 243 fprintf(stderr, "Invalid object type.\n");
279 return 1; 244 return 1;
280 } 245 }
281 246
282 prop_id = atoi(argv[3]); 247 prop_id = atoi(argv[2]);
283 value = atoll(argv[4]); 248 value = atoll(argv[3]);
284 249
285 return drmModeObjectSetProperty(fd, obj_id, obj_type, prop_id, value); 250 return drmModeObjectSetProperty(fd, obj_id, obj_type, prop_id, value);
286} 251}
287 252
288static void printUsage(void) 253static void usage(const char *program)
289{ 254{
290 printf("Usage:\n" 255 printf("Usage:\n"
291" proptest\n" 256" %s [options]\n"
292" proptest [obj id] [obj type] [prop id] [value]\n" 257" %s [options] [obj id] [obj type] [prop id] [value]\n"
258"\n"
259"options:\n"
260" -D DEVICE use the given device\n"
261" -M MODULE use the given driver\n"
293"\n" 262"\n"
294"The first form just prints all the existing properties. The second one is\n" 263"The first form just prints all the existing properties. The second one is\n"
295"used to set the value of a specified property. The object type can be one of\n" 264"used to set the value of a specified property. The object type can be one of\n"
@@ -298,26 +267,37 @@ static void printUsage(void)
298"\n" 267"\n"
299"Example:\n" 268"Example:\n"
300" proptest 7 connector 2 1\n" 269" proptest 7 connector 2 1\n"
301"will set property 2 of connector 7 to 1\n"); 270"will set property 2 of connector 7 to 1\n", program, program);
302} 271}
303 272
304int main(int argc, char *argv[]) 273int main(int argc, char *argv[])
305{ 274{
306 char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "msm" }; 275 static const char optstr[] = "D:M:";
307 unsigned int i, ret = 0; 276 int c, args, ret = 0;
277 char *device = NULL;
278 char *module = NULL;
279
280 while ((c = getopt(argc, argv, optstr)) != -1) {
281 switch (c) {
282 case 'D':
283 device = optarg;
284 break;
285
286 case 'M':
287 module = optarg;
288 break;
308 289
309 for (i = 0; i < ARRAY_SIZE(modules); i++){ 290 default:
310 fd = drmOpen(modules[i], NULL); 291 usage(argv[0]);
311 if (fd >= 0) {
312 printf("Module %s loaded.\n", modules[i]);
313 break; 292 break;
314 } 293 }
315 } 294 }
316 295
317 if (i == ARRAY_SIZE(modules)) { 296 args = argc - optind;
318 fprintf(stderr, "Failed to load drm modules.\n"); 297
298 fd = util_open(module, device);
299 if (fd < 0)
319 return 1; 300 return 1;
320 }
321 301
322 res = drmModeGetResources(fd); 302 res = drmModeGetResources(fd);
323 if (!res) { 303 if (!res) {
@@ -327,12 +307,12 @@ int main(int argc, char *argv[])
327 goto done; 307 goto done;
328 } 308 }
329 309
330 if (argc < 2) { 310 if (args < 1) {
331 listAllProperties(); 311 listAllProperties();
332 } else if (argc == 5) { 312 } else if (args == 4) {
333 ret = setProperty(argv); 313 ret = setProperty(&argv[optind]);
334 } else { 314 } else {
335 printUsage(); 315 usage(argv[0]);
336 ret = 1; 316 ret = 1;
337 } 317 }
338 318
diff --git a/tests/radeon/Makefile.am b/tests/radeon/Makefile.am
index 1775669e..9da76259 100644
--- a/tests/radeon/Makefile.am
+++ b/tests/radeon/Makefile.am
@@ -1,4 +1,5 @@
1AM_CFLAGS = \ 1AM_CFLAGS = \
2 $(WARN_CFLAGS)\
2 -I $(top_srcdir)/include/drm \ 3 -I $(top_srcdir)/include/drm \
3 -I $(top_srcdir) 4 -I $(top_srcdir)
4 5
@@ -10,5 +11,4 @@ noinst_PROGRAMS = \
10radeon_ttm_SOURCES = \ 11radeon_ttm_SOURCES = \
11 rbo.c \ 12 rbo.c \
12 rbo.h \ 13 rbo.h \
13 list.h \
14 radeon_ttm.c 14 radeon_ttm.c
diff --git a/tests/radeon/list.h b/tests/radeon/list.h
deleted file mode 100644
index 305c903e..00000000
--- a/tests/radeon/list.h
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 */
27
28/**
29 * \file
30 * List macros heavily inspired by the Linux kernel
31 * list handling. No list looping yet.
32 *
33 * Is not threadsafe, so common operations need to
34 * be protected using an external mutex.
35 */
36#ifndef _U_DOUBLE_LIST_H_
37#define _U_DOUBLE_LIST_H_
38
39#include <stddef.h>
40
41struct list_head
42{
43 struct list_head *prev;
44 struct list_head *next;
45};
46
47static void list_inithead(struct list_head *item)
48{
49 item->prev = item;
50 item->next = item;
51}
52
53static void list_add(struct list_head *item, struct list_head *list)
54{
55 item->prev = list;
56 item->next = list->next;
57 list->next->prev = item;
58 list->next = item;
59}
60
61static void list_addtail(struct list_head *item, struct list_head *list)
62{
63 item->next = list;
64 item->prev = list->prev;
65 list->prev->next = item;
66 list->prev = item;
67}
68
69static void list_replace(struct list_head *from, struct list_head *to)
70{
71 to->prev = from->prev;
72 to->next = from->next;
73 from->next->prev = to;
74 from->prev->next = to;
75}
76
77static void list_del(struct list_head *item)
78{
79 item->prev->next = item->next;
80 item->next->prev = item->prev;
81}
82
83static void list_delinit(struct list_head *item)
84{
85 item->prev->next = item->next;
86 item->next->prev = item->prev;
87 item->next = item;
88 item->prev = item;
89}
90
91#define LIST_INITHEAD(__item) list_inithead(__item)
92#define LIST_ADD(__item, __list) list_add(__item, __list)
93#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
94#define LIST_REPLACE(__from, __to) list_replace(__from, __to)
95#define LIST_DEL(__item) list_del(__item)
96#define LIST_DELINIT(__item) list_delinit(__item)
97
98#define LIST_ENTRY(__type, __item, __field) \
99 ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
100
101#define LIST_IS_EMPTY(__list) \
102 ((__list)->next == (__list))
103
104#ifndef container_of
105#define container_of(ptr, sample, member) \
106 (void *)((char *)(ptr) \
107 - ((char *)&(sample)->member - (char *)(sample)))
108#endif
109
110#define LIST_FOR_EACH_ENTRY(pos, head, member) \
111 for (pos = container_of((head)->next, pos, member); \
112 &pos->member != (head); \
113 pos = container_of(pos->member.next, pos, member))
114
115#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
116 for (pos = container_of((head)->next, pos, member), \
117 storage = container_of(pos->member.next, pos, member); \
118 &pos->member != (head); \
119 pos = storage, storage = container_of(storage->member.next, storage, member))
120
121#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
122 for (pos = container_of((head)->prev, pos, member), \
123 storage = container_of(pos->member.prev, pos, member); \
124 &pos->member != (head); \
125 pos = storage, storage = container_of(storage->member.prev, storage, member))
126
127#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
128 for (pos = container_of((start), pos, member); \
129 &pos->member != (head); \
130 pos = container_of(pos->member.next, pos, member))
131
132#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
133 for (pos = container_of((start), pos, member); \
134 &pos->member != (head); \
135 pos = container_of(pos->member.prev, pos, member))
136
137#endif /*_U_DOUBLE_LIST_H_*/
diff --git a/tests/radeon/radeon_ttm.c b/tests/radeon/radeon_ttm.c
index ac3297aa..8346e85b 100644
--- a/tests/radeon/radeon_ttm.c
+++ b/tests/radeon/radeon_ttm.c
@@ -32,7 +32,7 @@
32/* allocate as many single page bo to try to starve the kernel 32/* allocate as many single page bo to try to starve the kernel
33 * memory zone (below highmem) 33 * memory zone (below highmem)
34 */ 34 */
35void ttm_starve_kernel_private_memory(int fd) 35static void ttm_starve_kernel_private_memory(int fd)
36{ 36{
37 struct list_head list; 37 struct list_head list;
38 struct rbo *bo, *tmp; 38 struct rbo *bo, *tmp;
@@ -55,7 +55,7 @@ void ttm_starve_kernel_private_memory(int fd)
55 } 55 }
56} 56}
57 57
58int radeon_open_fd(void) 58static int radeon_open_fd(void)
59{ 59{
60 return drmOpen("radeon", NULL); 60 return drmOpen("radeon", NULL);
61} 61}
diff --git a/tests/radeon/rbo.h b/tests/radeon/rbo.h
index c25c73a4..9164091d 100644
--- a/tests/radeon/rbo.h
+++ b/tests/radeon/rbo.h
@@ -26,7 +26,7 @@
26#ifndef RBO_H 26#ifndef RBO_H
27#define RBO_H 27#define RBO_H
28 28
29#include "list.h" 29#include "util_double_list.h"
30 30
31struct rbo { 31struct rbo {
32 struct list_head list; 32 struct list_head list;
diff --git a/tests/random.c b/tests/random.c
new file mode 100644
index 00000000..13d4c805
--- /dev/null
+++ b/tests/random.c
@@ -0,0 +1,120 @@
1/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation
2 * Created: Mon Apr 19 08:28:13 1999 by faith@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
27 *
28 * DESCRIPTION
29 *
30 * This file contains a simple, straightforward implementation of the Park
31 * & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer
32 * multiplicative linear congruential generator (MLCG) with a period of
33 * 2^31-1.
34 *
35 * This implementation is intended to provide a reliable, portable PRNG
36 * that is suitable for testing a hash table implementation and for
37 * implementing skip lists.
38 *
39 * FUTURE ENHANCEMENTS
40 *
41 * If initial seeds are not selected randomly, two instances of the PRNG
42 * can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique
43 * that can eliminate this problem.
44 *
45 * If PRNGs are used for simulation, the period of the current
46 * implementation may be too short. [LE88] discusses methods of combining
47 * MLCGs to produce much longer periods, and suggests some alternative
48 * values for A and M. [LE90 and Sch92] also provide information on
49 * long-period PRNGs.
50 *
51 * REFERENCES
52 *
53 * [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2:
54 * Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981.
55 *
56 * [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number
57 * Generators". CACM 31(6), June 1988, pp. 742-774.
58 *
59 * [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10,
60 * October 1990, pp. 85-97.
61 *
62 * [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators:
63 * Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201.
64 *
65 * [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit
66 * CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40.
67 *
68 * [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In
69 * "Technical Correspondence: Remarks on Choosing and Implementing Random
70 * Number Generators". CACM 36(7), July 1993, pp. 105-110.
71 *
72 */
73
74#include <stdio.h>
75#include <stdlib.h>
76
77#include "xf86drm.h"
78#include "xf86drmRandom.h"
79
80static void check_period(unsigned long seed)
81{
82 unsigned long count = 0;
83 unsigned long initial;
84 void *state;
85
86 state = drmRandomCreate(seed);
87 initial = drmRandom(state);
88 ++count;
89 while (initial != drmRandom(state)) {
90 if (!++count) break;
91 }
92 printf("With seed of %10lu, period = %10lu (0x%08lx)\n",
93 seed, count, count);
94 drmRandomDestroy(state);
95}
96
97int main(void)
98{
99 RandomState *state;
100 int i;
101 int ret;
102 unsigned long rand;
103
104 state = drmRandomCreate(1);
105 for (i = 0; i < 10000; i++) {
106 rand = drmRandom(state);
107 }
108 ret = rand != state->check;
109 printf("After 10000 iterations: %lu (%lu expected): %s\n",
110 rand, state->check,
111 ret ? "*INCORRECT*" : "CORRECT");
112 drmRandomDestroy(state);
113
114 printf("Checking periods...\n");
115 check_period(1);
116 check_period(2);
117 check_period(31415926);
118
119 return ret;
120}
diff --git a/tests/setversion.c b/tests/setversion.c
index 5a5d01cd..2f7b529a 100644
--- a/tests/setversion.c
+++ b/tests/setversion.c
@@ -27,6 +27,7 @@
27 27
28#include <limits.h> 28#include <limits.h>
29#include <string.h> 29#include <string.h>
30#include <sys/ioctl.h>
30#include "drmtest.h" 31#include "drmtest.h"
31 32
32/** 33/**
diff --git a/tests/tegra/Makefile.am b/tests/tegra/Makefile.am
index ca63d92f..8e625c8f 100644
--- a/tests/tegra/Makefile.am
+++ b/tests/tegra/Makefile.am
@@ -3,7 +3,7 @@ AM_CPPFLAGS = \
3 -I$(top_srcdir)/tegra \ 3 -I$(top_srcdir)/tegra \
4 -I$(top_srcdir) 4 -I$(top_srcdir)
5 5
6AM_CFLAGS = -Wall -Werror 6AM_CFLAGS = $(WARN_CFLAGS)
7 7
8LDADD = \ 8LDADD = \
9 ../../tegra/libdrm_tegra.la \ 9 ../../tegra/libdrm_tegra.la \
diff --git a/tests/updatedraw.c b/tests/updatedraw.c
index a61eb151..d01fa96d 100644
--- a/tests/updatedraw.c
+++ b/tests/updatedraw.c
@@ -25,6 +25,7 @@
25 * 25 *
26 */ 26 */
27 27
28#include <sys/ioctl.h>
28#include "drmtest.h" 29#include "drmtest.h"
29 30
30static void 31static void
@@ -121,7 +122,7 @@ static int rm_drawable(int fd, int drawable, int fail)
121 */ 122 */
122int main(int argc, char **argv) 123int main(int argc, char **argv)
123{ 124{
124 int fd, ret, d1, d2; 125 int fd, d1, d2;
125 126
126 if (getuid() != 0) { 127 if (getuid() != 0) {
127 fprintf(stderr, "updatedraw test requires root, skipping\n"); 128 fprintf(stderr, "updatedraw test requires root, skipping\n");
diff --git a/tests/util/Android.mk b/tests/util/Android.mk
new file mode 100644
index 00000000..73bc6805
--- /dev/null
+++ b/tests/util/Android.mk
@@ -0,0 +1,39 @@
1#
2# Copyright © 2015 NVIDIA Corporation
3#
4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the "Software"),
6# to deal in the Software without restriction, including without limitation
7# the rights to use, copy, modify, merge, publish, distribute, sublicense,
8# and/or sell copies of the Software, and to permit persons to whom the
9# Software is furnished to do so, subject to the following conditions:
10#
11# The above copyright notice and this permission notice (including the next
12# paragraph) shall be included in all copies or substantial portions of the
13# Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21# IN THE SOFTWARE.
22#
23
24LOCAL_PATH := $(call my-dir)
25
26include $(CLEAR_VARS)
27include $(LOCAL_PATH)/Makefile.sources
28
29LOCAL_MODULE := libdrm_util
30LOCAL_MODULE_TAGS := optional
31
32LOCAL_SHARED_LIBRARIES := libdrm
33
34LOCAL_SRC_FILES := $(UTIL_FILES)
35
36# avoid name clashes by requiring users to include util/*.h
37LOCAL_EXPORT_C_INCLUDE_DIRS := $(dir $(LOCAL_PATH))
38
39include $(BUILD_STATIC_LIBRARY)
diff --git a/tests/util/Makefile.am b/tests/util/Makefile.am
new file mode 100644
index 00000000..f8e0b171
--- /dev/null
+++ b/tests/util/Makefile.am
@@ -0,0 +1,13 @@
1include Makefile.sources
2
3noinst_LTLIBRARIES = \
4 libutil.la
5
6libutil_la_CPPFLAGS = \
7 -I$(top_srcdir)/include/drm \
8 -I$(top_srcdir)
9
10libutil_la_CFLAGS = \
11 $(CAIRO_CFLAGS)
12
13libutil_la_SOURCES = $(UTIL_FILES)
diff --git a/tests/util/Makefile.sources b/tests/util/Makefile.sources
new file mode 100644
index 00000000..e5f85113
--- /dev/null
+++ b/tests/util/Makefile.sources
@@ -0,0 +1,8 @@
1UTIL_FILES := \
2 common.h \
3 format.c \
4 format.h \
5 kms.c \
6 kms.h \
7 pattern.c \
8 pattern.h
diff --git a/tests/util/common.h b/tests/util/common.h
new file mode 100644
index 00000000..5d572c2d
--- /dev/null
+++ b/tests/util/common.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright 2008 Tungsten Graphics
3 * Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25
26#ifndef UTIL_COMMON_H
27#define UTIL_COMMON_H
28
29#ifndef ARRAY_SIZE
30#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
31#endif
32
33#endif /* UTIL_COMMON_H */
diff --git a/tests/util/format.c b/tests/util/format.c
new file mode 100644
index 00000000..043cfe7f
--- /dev/null
+++ b/tests/util/format.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright 2008 Tungsten Graphics
3 * Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include <stdint.h>
31#include <stdlib.h>
32#include <string.h>
33
34#include <drm_fourcc.h>
35
36#include "common.h"
37#include "format.h"
38
39#define MAKE_RGB_INFO(rl, ro, gl, go, bl, bo, al, ao) \
40 .rgb = { { (rl), (ro) }, { (gl), (go) }, { (bl), (bo) }, { (al), (ao) } }
41
42#define MAKE_YUV_INFO(order, xsub, ysub, chroma_stride) \
43 .yuv = { (order), (xsub), (ysub), (chroma_stride) }
44
45static const struct util_format_info format_info[] = {
46 /* YUV packed */
47 { DRM_FORMAT_UYVY, "UYVY", MAKE_YUV_INFO(YUV_YCbCr | YUV_CY, 2, 2, 2) },
48 { DRM_FORMAT_VYUY, "VYUY", MAKE_YUV_INFO(YUV_YCrCb | YUV_CY, 2, 2, 2) },
49 { DRM_FORMAT_YUYV, "YUYV", MAKE_YUV_INFO(YUV_YCbCr | YUV_YC, 2, 2, 2) },
50 { DRM_FORMAT_YVYU, "YVYU", MAKE_YUV_INFO(YUV_YCrCb | YUV_YC, 2, 2, 2) },
51 /* YUV semi-planar */
52 { DRM_FORMAT_NV12, "NV12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 2) },
53 { DRM_FORMAT_NV21, "NV21", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 2) },
54 { DRM_FORMAT_NV16, "NV16", MAKE_YUV_INFO(YUV_YCbCr, 2, 1, 2) },
55 { DRM_FORMAT_NV61, "NV61", MAKE_YUV_INFO(YUV_YCrCb, 2, 1, 2) },
56 /* YUV planar */
57 { DRM_FORMAT_YUV420, "YU12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 1) },
58 { DRM_FORMAT_YVU420, "YV12", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 1) },
59 /* RGB16 */
60 { DRM_FORMAT_ARGB4444, "AR12", MAKE_RGB_INFO(4, 8, 4, 4, 4, 0, 4, 12) },
61 { DRM_FORMAT_XRGB4444, "XR12", MAKE_RGB_INFO(4, 8, 4, 4, 4, 0, 0, 0) },
62 { DRM_FORMAT_ABGR4444, "AB12", MAKE_RGB_INFO(4, 0, 4, 4, 4, 8, 4, 12) },
63 { DRM_FORMAT_XBGR4444, "XB12", MAKE_RGB_INFO(4, 0, 4, 4, 4, 8, 0, 0) },
64 { DRM_FORMAT_RGBA4444, "RA12", MAKE_RGB_INFO(4, 12, 4, 8, 4, 4, 4, 0) },
65 { DRM_FORMAT_RGBX4444, "RX12", MAKE_RGB_INFO(4, 12, 4, 8, 4, 4, 0, 0) },
66 { DRM_FORMAT_BGRA4444, "BA12", MAKE_RGB_INFO(4, 4, 4, 8, 4, 12, 4, 0) },
67 { DRM_FORMAT_BGRX4444, "BX12", MAKE_RGB_INFO(4, 4, 4, 8, 4, 12, 0, 0) },
68 { DRM_FORMAT_ARGB1555, "AR15", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 1, 15) },
69 { DRM_FORMAT_XRGB1555, "XR15", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 0, 0) },
70 { DRM_FORMAT_ABGR1555, "AB15", MAKE_RGB_INFO(5, 0, 5, 5, 5, 10, 1, 15) },
71 { DRM_FORMAT_XBGR1555, "XB15", MAKE_RGB_INFO(5, 0, 5, 5, 5, 10, 0, 0) },
72 { DRM_FORMAT_RGBA5551, "RA15", MAKE_RGB_INFO(5, 11, 5, 6, 5, 1, 1, 0) },
73 { DRM_FORMAT_RGBX5551, "RX15", MAKE_RGB_INFO(5, 11, 5, 6, 5, 1, 0, 0) },
74 { DRM_FORMAT_BGRA5551, "BA15", MAKE_RGB_INFO(5, 1, 5, 6, 5, 11, 1, 0) },
75 { DRM_FORMAT_BGRX5551, "BX15", MAKE_RGB_INFO(5, 1, 5, 6, 5, 11, 0, 0) },
76 { DRM_FORMAT_RGB565, "RG16", MAKE_RGB_INFO(5, 11, 6, 5, 5, 0, 0, 0) },
77 { DRM_FORMAT_BGR565, "BG16", MAKE_RGB_INFO(5, 0, 6, 5, 5, 11, 0, 0) },
78 /* RGB24 */
79 { DRM_FORMAT_BGR888, "BG24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 0, 0) },
80 { DRM_FORMAT_RGB888, "RG24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },
81 /* RGB32 */
82 { DRM_FORMAT_ARGB8888, "AR24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 8, 24) },
83 { DRM_FORMAT_XRGB8888, "XR24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },
84 { DRM_FORMAT_ABGR8888, "AB24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 8, 24) },
85 { DRM_FORMAT_XBGR8888, "XB24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 0, 0) },
86 { DRM_FORMAT_RGBA8888, "RA24", MAKE_RGB_INFO(8, 24, 8, 16, 8, 8, 8, 0) },
87 { DRM_FORMAT_RGBX8888, "RX24", MAKE_RGB_INFO(8, 24, 8, 16, 8, 8, 0, 0) },
88 { DRM_FORMAT_BGRA8888, "BA24", MAKE_RGB_INFO(8, 8, 8, 16, 8, 24, 8, 0) },
89 { DRM_FORMAT_BGRX8888, "BX24", MAKE_RGB_INFO(8, 8, 8, 16, 8, 24, 0, 0) },
90 { DRM_FORMAT_ARGB2101010, "AR30", MAKE_RGB_INFO(10, 20, 10, 10, 10, 0, 2, 30) },
91 { DRM_FORMAT_XRGB2101010, "XR30", MAKE_RGB_INFO(10, 20, 10, 10, 10, 0, 0, 0) },
92 { DRM_FORMAT_ABGR2101010, "AB30", MAKE_RGB_INFO(10, 0, 10, 10, 10, 20, 2, 30) },
93 { DRM_FORMAT_XBGR2101010, "XB30", MAKE_RGB_INFO(10, 0, 10, 10, 10, 20, 0, 0) },
94 { DRM_FORMAT_RGBA1010102, "RA30", MAKE_RGB_INFO(10, 22, 10, 12, 10, 2, 2, 0) },
95 { DRM_FORMAT_RGBX1010102, "RX30", MAKE_RGB_INFO(10, 22, 10, 12, 10, 2, 0, 0) },
96 { DRM_FORMAT_BGRA1010102, "BA30", MAKE_RGB_INFO(10, 2, 10, 12, 10, 22, 2, 0) },
97 { DRM_FORMAT_BGRX1010102, "BX30", MAKE_RGB_INFO(10, 2, 10, 12, 10, 22, 0, 0) },
98};
99
100uint32_t util_format_fourcc(const char *name)
101{
102 unsigned int i;
103
104 for (i = 0; i < ARRAY_SIZE(format_info); i++)
105 if (!strcmp(format_info[i].name, name))
106 return format_info[i].format;
107
108 return 0;
109}
110
111const struct util_format_info *util_format_info_find(uint32_t format)
112{
113 unsigned int i;
114
115 for (i = 0; i < ARRAY_SIZE(format_info); i++)
116 if (format_info[i].format == format)
117 return &format_info[i];
118
119 return NULL;
120}
diff --git a/tests/util/format.h b/tests/util/format.h
new file mode 100644
index 00000000..2ce1c021
--- /dev/null
+++ b/tests/util/format.h
@@ -0,0 +1,65 @@
1/*
2 * Copyright 2008 Tungsten Graphics
3 * Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25
26#ifndef UTIL_FORMAT_H
27#define UTIL_FORMAT_H
28
29struct util_color_component {
30 unsigned int length;
31 unsigned int offset;
32};
33
34struct util_rgb_info {
35 struct util_color_component red;
36 struct util_color_component green;
37 struct util_color_component blue;
38 struct util_color_component alpha;
39};
40
41enum util_yuv_order {
42 YUV_YCbCr = 1,
43 YUV_YCrCb = 2,
44 YUV_YC = 4,
45 YUV_CY = 8,
46};
47
48struct util_yuv_info {
49 enum util_yuv_order order;
50 unsigned int xsub;
51 unsigned int ysub;
52 unsigned int chroma_stride;
53};
54
55struct util_format_info {
56 uint32_t format;
57 const char *name;
58 const struct util_rgb_info rgb;
59 const struct util_yuv_info yuv;
60};
61
62uint32_t util_format_fourcc(const char *name);
63const struct util_format_info *util_format_info_find(uint32_t format);
64
65#endif /* UTIL_FORMAT_H */
diff --git a/tests/util/kms.c b/tests/util/kms.c
new file mode 100644
index 00000000..57b0191b
--- /dev/null
+++ b/tests/util/kms.c
@@ -0,0 +1,177 @@
1/*
2 * Copyright 2008 Tungsten Graphics
3 * Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25
26/*
27 * This fairly simple test program dumps output in a similar format to the
28 * "xrandr" tool everyone knows & loves. It's necessarily slightly different
29 * since the kernel separates outputs into encoder and connector structures,
30 * each with their own unique ID. The program also allows test testing of the
31 * memory management and mode setting APIs by allowing the user to specify a
32 * connector and mode to use for mode setting. If all works as expected, a
33 * blue background should be painted on the monitor attached to the specified
34 * connector after the selected mode is set.
35 *
36 * TODO: use cairo to write the mode info on the selected output once
37 * the mode has been programmed, along with possible test patterns.
38 */
39
40#ifdef HAVE_CONFIG_H
41#include "config.h"
42#endif
43
44#include <errno.h>
45#include <stdint.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49
50#include "xf86drm.h"
51#include "xf86drmMode.h"
52
53#include "common.h"
54
55struct type_name {
56 unsigned int type;
57 const char *name;
58};
59
60static const char *util_lookup_type_name(unsigned int type,
61 const struct type_name *table,
62 unsigned int count)
63{
64 unsigned int i;
65
66 for (i = 0; i < count; i++)
67 if (table[i].type == type)
68 return table[i].name;
69
70 return NULL;
71}
72
73static const struct type_name encoder_type_names[] = {
74 { DRM_MODE_ENCODER_NONE, "none" },
75 { DRM_MODE_ENCODER_DAC, "DAC" },
76 { DRM_MODE_ENCODER_TMDS, "TMDS" },
77 { DRM_MODE_ENCODER_LVDS, "LVDS" },
78 { DRM_MODE_ENCODER_TVDAC, "TVDAC" },
79 { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
80 { DRM_MODE_ENCODER_DSI, "DSI" },
81 { DRM_MODE_ENCODER_DPMST, "DPMST" },
82};
83
84const char *util_lookup_encoder_type_name(unsigned int type)
85{
86 return util_lookup_type_name(type, encoder_type_names,
87 ARRAY_SIZE(encoder_type_names));
88}
89
90static const struct type_name connector_status_names[] = {
91 { DRM_MODE_CONNECTED, "connected" },
92 { DRM_MODE_DISCONNECTED, "disconnected" },
93 { DRM_MODE_UNKNOWNCONNECTION, "unknown" },
94};
95
96const char *util_lookup_connector_status_name(unsigned int status)
97{
98 return util_lookup_type_name(status, connector_status_names,
99 ARRAY_SIZE(connector_status_names));
100}
101
102static const struct type_name connector_type_names[] = {
103 { DRM_MODE_CONNECTOR_Unknown, "unknown" },
104 { DRM_MODE_CONNECTOR_VGA, "VGA" },
105 { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
106 { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
107 { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
108 { DRM_MODE_CONNECTOR_Composite, "composite" },
109 { DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
110 { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
111 { DRM_MODE_CONNECTOR_Component, "component" },
112 { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
113 { DRM_MODE_CONNECTOR_DisplayPort, "DP" },
114 { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
115 { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
116 { DRM_MODE_CONNECTOR_TV, "TV" },
117 { DRM_MODE_CONNECTOR_eDP, "eDP" },
118 { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
119 { DRM_MODE_CONNECTOR_DSI, "DSI" },
120};
121
122const char *util_lookup_connector_type_name(unsigned int type)
123{
124 return util_lookup_type_name(type, connector_type_names,
125 ARRAY_SIZE(connector_type_names));
126}
127
128static const char * const modules[] = {
129 "i915",
130 "radeon",
131 "nouveau",
132 "vmwgfx",
133 "omapdrm",
134 "exynos",
135 "tilcdc",
136 "msm",
137 "sti",
138 "tegra",
139 "imx-drm",
140 "rockchip",
141 "atmel-hlcdc",
142};
143
144int util_open(const char *device, const char *module)
145{
146 int fd;
147
148 if (module) {
149 fd = drmOpen(module, device);
150 if (fd < 0) {
151 fprintf(stderr, "failed to open device '%s': %s\n",
152 module, strerror(errno));
153 return -errno;
154 }
155 } else {
156 unsigned int i;
157
158 for (i = 0; i < ARRAY_SIZE(modules); i++) {
159 printf("trying to open device '%s'...", modules[i]);
160
161 fd = drmOpen(modules[i], device);
162 if (fd < 0) {
163 printf("failed\n");
164 } else {
165 printf("done\n");
166 break;
167 }
168 }
169
170 if (fd < 0) {
171 fprintf(stderr, "no device found\n");
172 return -ENODEV;
173 }
174 }
175
176 return fd;
177}
diff --git a/tests/util/kms.h b/tests/util/kms.h
new file mode 100644
index 00000000..dde2ed2c
--- /dev/null
+++ b/tests/util/kms.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright 2008 Tungsten Graphics
3 * Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25
26#ifndef UTIL_KMS_H
27#define UTIL_KMS_H
28
29const char *util_lookup_encoder_type_name(unsigned int type);
30const char *util_lookup_connector_status_name(unsigned int type);
31const char *util_lookup_connector_type_name(unsigned int type);
32
33int util_open(const char *device, const char *module);
34
35#endif /* UTIL_KMS_H */
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
new file mode 100644
index 00000000..00b08a8c
--- /dev/null
+++ b/tests/util/pattern.c
@@ -0,0 +1,870 @@
1/*
2 * Copyright 2008 Tungsten Graphics
3 * Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include <stdint.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34
35#include <drm_fourcc.h>
36
37#ifdef HAVE_CAIRO
38#include <cairo.h>
39#include <math.h>
40#endif
41
42#include "format.h"
43#include "pattern.h"
44
45struct color_rgb24 {
46 unsigned int value:24;
47} __attribute__((__packed__));
48
49struct color_yuv {
50 unsigned char y;
51 unsigned char u;
52 unsigned char v;
53};
54
55#define MAKE_YUV_601_Y(r, g, b) \
56 ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16)
57#define MAKE_YUV_601_U(r, g, b) \
58 (((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128)
59#define MAKE_YUV_601_V(r, g, b) \
60 (((112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128)
61
62#define MAKE_YUV_601(r, g, b) \
63 { .y = MAKE_YUV_601_Y(r, g, b), \
64 .u = MAKE_YUV_601_U(r, g, b), \
65 .v = MAKE_YUV_601_V(r, g, b) }
66
67#define MAKE_RGBA(rgb, r, g, b, a) \
68 ((((r) >> (8 - (rgb)->red.length)) << (rgb)->red.offset) | \
69 (((g) >> (8 - (rgb)->green.length)) << (rgb)->green.offset) | \
70 (((b) >> (8 - (rgb)->blue.length)) << (rgb)->blue.offset) | \
71 (((a) >> (8 - (rgb)->alpha.length)) << (rgb)->alpha.offset))
72
73#define MAKE_RGB24(rgb, r, g, b) \
74 { .value = MAKE_RGBA(rgb, r, g, b, 0) }
75
76static void fill_smpte_yuv_planar(const struct util_yuv_info *yuv,
77 unsigned char *y_mem, unsigned char *u_mem,
78 unsigned char *v_mem, unsigned int width,
79 unsigned int height, unsigned int stride)
80{
81 const struct color_yuv colors_top[] = {
82 MAKE_YUV_601(191, 192, 192), /* grey */
83 MAKE_YUV_601(192, 192, 0), /* yellow */
84 MAKE_YUV_601(0, 192, 192), /* cyan */
85 MAKE_YUV_601(0, 192, 0), /* green */
86 MAKE_YUV_601(192, 0, 192), /* magenta */
87 MAKE_YUV_601(192, 0, 0), /* red */
88 MAKE_YUV_601(0, 0, 192), /* blue */
89 };
90 const struct color_yuv colors_middle[] = {
91 MAKE_YUV_601(0, 0, 192), /* blue */
92 MAKE_YUV_601(19, 19, 19), /* black */
93 MAKE_YUV_601(192, 0, 192), /* magenta */
94 MAKE_YUV_601(19, 19, 19), /* black */
95 MAKE_YUV_601(0, 192, 192), /* cyan */
96 MAKE_YUV_601(19, 19, 19), /* black */
97 MAKE_YUV_601(192, 192, 192), /* grey */
98 };
99 const struct color_yuv colors_bottom[] = {
100 MAKE_YUV_601(0, 33, 76), /* in-phase */
101 MAKE_YUV_601(255, 255, 255), /* super white */
102 MAKE_YUV_601(50, 0, 106), /* quadrature */
103 MAKE_YUV_601(19, 19, 19), /* black */
104 MAKE_YUV_601(9, 9, 9), /* 3.5% */
105 MAKE_YUV_601(19, 19, 19), /* 7.5% */
106 MAKE_YUV_601(29, 29, 29), /* 11.5% */
107 MAKE_YUV_601(19, 19, 19), /* black */
108 };
109 unsigned int cs = yuv->chroma_stride;
110 unsigned int xsub = yuv->xsub;
111 unsigned int ysub = yuv->ysub;
112 unsigned int x;
113 unsigned int y;
114
115 /* Luma */
116 for (y = 0; y < height * 6 / 9; ++y) {
117 for (x = 0; x < width; ++x)
118 y_mem[x] = colors_top[x * 7 / width].y;
119 y_mem += stride;
120 }
121
122 for (; y < height * 7 / 9; ++y) {
123 for (x = 0; x < width; ++x)
124 y_mem[x] = colors_middle[x * 7 / width].y;
125 y_mem += stride;
126 }
127
128 for (; y < height; ++y) {
129 for (x = 0; x < width * 5 / 7; ++x)
130 y_mem[x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
131 for (; x < width * 6 / 7; ++x)
132 y_mem[x] = colors_bottom[(x - width * 5 / 7) * 3
133 / (width / 7) + 4].y;
134 for (; x < width; ++x)
135 y_mem[x] = colors_bottom[7].y;
136 y_mem += stride;
137 }
138
139 /* Chroma */
140 for (y = 0; y < height / ysub * 6 / 9; ++y) {
141 for (x = 0; x < width; x += xsub) {
142 u_mem[x*cs/xsub] = colors_top[x * 7 / width].u;
143 v_mem[x*cs/xsub] = colors_top[x * 7 / width].v;
144 }
145 u_mem += stride * cs / xsub;
146 v_mem += stride * cs / xsub;
147 }
148
149 for (; y < height / ysub * 7 / 9; ++y) {
150 for (x = 0; x < width; x += xsub) {
151 u_mem[x*cs/xsub] = colors_middle[x * 7 / width].u;
152 v_mem[x*cs/xsub] = colors_middle[x * 7 / width].v;
153 }
154 u_mem += stride * cs / xsub;
155 v_mem += stride * cs / xsub;
156 }
157
158 for (; y < height / ysub; ++y) {
159 for (x = 0; x < width * 5 / 7; x += xsub) {
160 u_mem[x*cs/xsub] =
161 colors_bottom[x * 4 / (width * 5 / 7)].u;
162 v_mem[x*cs/xsub] =
163 colors_bottom[x * 4 / (width * 5 / 7)].v;
164 }
165 for (; x < width * 6 / 7; x += xsub) {
166 u_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
167 3 / (width / 7) + 4].u;
168 v_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
169 3 / (width / 7) + 4].v;
170 }
171 for (; x < width; x += xsub) {
172 u_mem[x*cs/xsub] = colors_bottom[7].u;
173 v_mem[x*cs/xsub] = colors_bottom[7].v;
174 }
175 u_mem += stride * cs / xsub;
176 v_mem += stride * cs / xsub;
177 }
178}
179
180static void fill_smpte_yuv_packed(const struct util_yuv_info *yuv, void *mem,
181 unsigned int width, unsigned int height,
182 unsigned int stride)
183{
184 const struct color_yuv colors_top[] = {
185 MAKE_YUV_601(191, 192, 192), /* grey */
186 MAKE_YUV_601(192, 192, 0), /* yellow */
187 MAKE_YUV_601(0, 192, 192), /* cyan */
188 MAKE_YUV_601(0, 192, 0), /* green */
189 MAKE_YUV_601(192, 0, 192), /* magenta */
190 MAKE_YUV_601(192, 0, 0), /* red */
191 MAKE_YUV_601(0, 0, 192), /* blue */
192 };
193 const struct color_yuv colors_middle[] = {
194 MAKE_YUV_601(0, 0, 192), /* blue */
195 MAKE_YUV_601(19, 19, 19), /* black */
196 MAKE_YUV_601(192, 0, 192), /* magenta */
197 MAKE_YUV_601(19, 19, 19), /* black */
198 MAKE_YUV_601(0, 192, 192), /* cyan */
199 MAKE_YUV_601(19, 19, 19), /* black */
200 MAKE_YUV_601(192, 192, 192), /* grey */
201 };
202 const struct color_yuv colors_bottom[] = {
203 MAKE_YUV_601(0, 33, 76), /* in-phase */
204 MAKE_YUV_601(255, 255, 255), /* super white */
205 MAKE_YUV_601(50, 0, 106), /* quadrature */
206 MAKE_YUV_601(19, 19, 19), /* black */
207 MAKE_YUV_601(9, 9, 9), /* 3.5% */
208 MAKE_YUV_601(19, 19, 19), /* 7.5% */
209 MAKE_YUV_601(29, 29, 29), /* 11.5% */
210 MAKE_YUV_601(19, 19, 19), /* black */
211 };
212 unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
213 unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
214 unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
215 unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
216 unsigned int x;
217 unsigned int y;
218
219 /* Luma */
220 for (y = 0; y < height * 6 / 9; ++y) {
221 for (x = 0; x < width; ++x)
222 y_mem[2*x] = colors_top[x * 7 / width].y;
223 y_mem += stride;
224 }
225
226 for (; y < height * 7 / 9; ++y) {
227 for (x = 0; x < width; ++x)
228 y_mem[2*x] = colors_middle[x * 7 / width].y;
229 y_mem += stride;
230 }
231
232 for (; y < height; ++y) {
233 for (x = 0; x < width * 5 / 7; ++x)
234 y_mem[2*x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
235 for (; x < width * 6 / 7; ++x)
236 y_mem[2*x] = colors_bottom[(x - width * 5 / 7) * 3
237 / (width / 7) + 4].y;
238 for (; x < width; ++x)
239 y_mem[2*x] = colors_bottom[7].y;
240 y_mem += stride;
241 }
242
243 /* Chroma */
244 for (y = 0; y < height * 6 / 9; ++y) {
245 for (x = 0; x < width; x += 2) {
246 c_mem[2*x+u] = colors_top[x * 7 / width].u;
247 c_mem[2*x+v] = colors_top[x * 7 / width].v;
248 }
249 c_mem += stride;
250 }
251
252 for (; y < height * 7 / 9; ++y) {
253 for (x = 0; x < width; x += 2) {
254 c_mem[2*x+u] = colors_middle[x * 7 / width].u;
255 c_mem[2*x+v] = colors_middle[x * 7 / width].v;
256 }
257 c_mem += stride;
258 }
259
260 for (; y < height; ++y) {
261 for (x = 0; x < width * 5 / 7; x += 2) {
262 c_mem[2*x+u] = colors_bottom[x * 4 / (width * 5 / 7)].u;
263 c_mem[2*x+v] = colors_bottom[x * 4 / (width * 5 / 7)].v;
264 }
265 for (; x < width * 6 / 7; x += 2) {
266 c_mem[2*x+u] = colors_bottom[(x - width * 5 / 7) *
267 3 / (width / 7) + 4].u;
268 c_mem[2*x+v] = colors_bottom[(x - width * 5 / 7) *
269 3 / (width / 7) + 4].v;
270 }
271 for (; x < width; x += 2) {
272 c_mem[2*x+u] = colors_bottom[7].u;
273 c_mem[2*x+v] = colors_bottom[7].v;
274 }
275 c_mem += stride;
276 }
277}
278
279static void fill_smpte_rgb16(const struct util_rgb_info *rgb, void *mem,
280 unsigned int width, unsigned int height,
281 unsigned int stride)
282{
283 const uint16_t colors_top[] = {
284 MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
285 MAKE_RGBA(rgb, 192, 192, 0, 255), /* yellow */
286 MAKE_RGBA(rgb, 0, 192, 192, 255), /* cyan */
287 MAKE_RGBA(rgb, 0, 192, 0, 255), /* green */
288 MAKE_RGBA(rgb, 192, 0, 192, 255), /* magenta */
289 MAKE_RGBA(rgb, 192, 0, 0, 255), /* red */
290 MAKE_RGBA(rgb, 0, 0, 192, 255), /* blue */
291 };
292 const uint16_t colors_middle[] = {
293 MAKE_RGBA(rgb, 0, 0, 192, 127), /* blue */
294 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
295 MAKE_RGBA(rgb, 192, 0, 192, 127), /* magenta */
296 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
297 MAKE_RGBA(rgb, 0, 192, 192, 127), /* cyan */
298 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
299 MAKE_RGBA(rgb, 192, 192, 192, 127), /* grey */
300 };
301 const uint16_t colors_bottom[] = {
302 MAKE_RGBA(rgb, 0, 33, 76, 255), /* in-phase */
303 MAKE_RGBA(rgb, 255, 255, 255, 255), /* super white */
304 MAKE_RGBA(rgb, 50, 0, 106, 255), /* quadrature */
305 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
306 MAKE_RGBA(rgb, 9, 9, 9, 255), /* 3.5% */
307 MAKE_RGBA(rgb, 19, 19, 19, 255), /* 7.5% */
308 MAKE_RGBA(rgb, 29, 29, 29, 255), /* 11.5% */
309 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
310 };
311 unsigned int x;
312 unsigned int y;
313
314 for (y = 0; y < height * 6 / 9; ++y) {
315 for (x = 0; x < width; ++x)
316 ((uint16_t *)mem)[x] = colors_top[x * 7 / width];
317 mem += stride;
318 }
319
320 for (; y < height * 7 / 9; ++y) {
321 for (x = 0; x < width; ++x)
322 ((uint16_t *)mem)[x] = colors_middle[x * 7 / width];
323 mem += stride;
324 }
325
326 for (; y < height; ++y) {
327 for (x = 0; x < width * 5 / 7; ++x)
328 ((uint16_t *)mem)[x] =
329 colors_bottom[x * 4 / (width * 5 / 7)];
330 for (; x < width * 6 / 7; ++x)
331 ((uint16_t *)mem)[x] =
332 colors_bottom[(x - width * 5 / 7) * 3
333 / (width / 7) + 4];
334 for (; x < width; ++x)
335 ((uint16_t *)mem)[x] = colors_bottom[7];
336 mem += stride;
337 }
338}
339
340static void fill_smpte_rgb24(const struct util_rgb_info *rgb, void *mem,
341 unsigned int width, unsigned int height,
342 unsigned int stride)
343{
344 const struct color_rgb24 colors_top[] = {
345 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
346 MAKE_RGB24(rgb, 192, 192, 0), /* yellow */
347 MAKE_RGB24(rgb, 0, 192, 192), /* cyan */
348 MAKE_RGB24(rgb, 0, 192, 0), /* green */
349 MAKE_RGB24(rgb, 192, 0, 192), /* magenta */
350 MAKE_RGB24(rgb, 192, 0, 0), /* red */
351 MAKE_RGB24(rgb, 0, 0, 192), /* blue */
352 };
353 const struct color_rgb24 colors_middle[] = {
354 MAKE_RGB24(rgb, 0, 0, 192), /* blue */
355 MAKE_RGB24(rgb, 19, 19, 19), /* black */
356 MAKE_RGB24(rgb, 192, 0, 192), /* magenta */
357 MAKE_RGB24(rgb, 19, 19, 19), /* black */
358 MAKE_RGB24(rgb, 0, 192, 192), /* cyan */
359 MAKE_RGB24(rgb, 19, 19, 19), /* black */
360 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
361 };
362 const struct color_rgb24 colors_bottom[] = {
363 MAKE_RGB24(rgb, 0, 33, 76), /* in-phase */
364 MAKE_RGB24(rgb, 255, 255, 255), /* super white */
365 MAKE_RGB24(rgb, 50, 0, 106), /* quadrature */
366 MAKE_RGB24(rgb, 19, 19, 19), /* black */
367 MAKE_RGB24(rgb, 9, 9, 9), /* 3.5% */
368 MAKE_RGB24(rgb, 19, 19, 19), /* 7.5% */
369 MAKE_RGB24(rgb, 29, 29, 29), /* 11.5% */
370 MAKE_RGB24(rgb, 19, 19, 19), /* black */
371 };
372 unsigned int x;
373 unsigned int y;
374
375 for (y = 0; y < height * 6 / 9; ++y) {
376 for (x = 0; x < width; ++x)
377 ((struct color_rgb24 *)mem)[x] =
378 colors_top[x * 7 / width];
379 mem += stride;
380 }
381
382 for (; y < height * 7 / 9; ++y) {
383 for (x = 0; x < width; ++x)
384 ((struct color_rgb24 *)mem)[x] =
385 colors_middle[x * 7 / width];
386 mem += stride;
387 }
388
389 for (; y < height; ++y) {
390 for (x = 0; x < width * 5 / 7; ++x)
391 ((struct color_rgb24 *)mem)[x] =
392 colors_bottom[x * 4 / (width * 5 / 7)];
393 for (; x < width * 6 / 7; ++x)
394 ((struct color_rgb24 *)mem)[x] =
395 colors_bottom[(x - width * 5 / 7) * 3
396 / (width / 7) + 4];
397 for (; x < width; ++x)
398 ((struct color_rgb24 *)mem)[x] = colors_bottom[7];
399 mem += stride;
400 }
401}
402
403static void fill_smpte_rgb32(const struct util_rgb_info *rgb, void *mem,
404 unsigned int width, unsigned int height,
405 unsigned int stride)
406{
407 const uint32_t colors_top[] = {
408 MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
409 MAKE_RGBA(rgb, 192, 192, 0, 255), /* yellow */
410 MAKE_RGBA(rgb, 0, 192, 192, 255), /* cyan */
411 MAKE_RGBA(rgb, 0, 192, 0, 255), /* green */
412 MAKE_RGBA(rgb, 192, 0, 192, 255), /* magenta */
413 MAKE_RGBA(rgb, 192, 0, 0, 255), /* red */
414 MAKE_RGBA(rgb, 0, 0, 192, 255), /* blue */
415 };
416 const uint32_t colors_middle[] = {
417 MAKE_RGBA(rgb, 0, 0, 192, 127), /* blue */
418 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
419 MAKE_RGBA(rgb, 192, 0, 192, 127), /* magenta */
420 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
421 MAKE_RGBA(rgb, 0, 192, 192, 127), /* cyan */
422 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
423 MAKE_RGBA(rgb, 192, 192, 192, 127), /* grey */
424 };
425 const uint32_t colors_bottom[] = {
426 MAKE_RGBA(rgb, 0, 33, 76, 255), /* in-phase */
427 MAKE_RGBA(rgb, 255, 255, 255, 255), /* super white */
428 MAKE_RGBA(rgb, 50, 0, 106, 255), /* quadrature */
429 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
430 MAKE_RGBA(rgb, 9, 9, 9, 255), /* 3.5% */
431 MAKE_RGBA(rgb, 19, 19, 19, 255), /* 7.5% */
432 MAKE_RGBA(rgb, 29, 29, 29, 255), /* 11.5% */
433 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
434 };
435 unsigned int x;
436 unsigned int y;
437
438 for (y = 0; y < height * 6 / 9; ++y) {
439 for (x = 0; x < width; ++x)
440 ((uint32_t *)mem)[x] = colors_top[x * 7 / width];
441 mem += stride;
442 }
443
444 for (; y < height * 7 / 9; ++y) {
445 for (x = 0; x < width; ++x)
446 ((uint32_t *)mem)[x] = colors_middle[x * 7 / width];
447 mem += stride;
448 }
449
450 for (; y < height; ++y) {
451 for (x = 0; x < width * 5 / 7; ++x)
452 ((uint32_t *)mem)[x] =
453 colors_bottom[x * 4 / (width * 5 / 7)];
454 for (; x < width * 6 / 7; ++x)
455 ((uint32_t *)mem)[x] =
456 colors_bottom[(x - width * 5 / 7) * 3
457 / (width / 7) + 4];
458 for (; x < width; ++x)
459 ((uint32_t *)mem)[x] = colors_bottom[7];
460 mem += stride;
461 }
462}
463
464static void fill_smpte(const struct util_format_info *info, void *planes[3],
465 unsigned int width, unsigned int height,
466 unsigned int stride)
467{
468 unsigned char *u, *v;
469
470 switch (info->format) {
471 case DRM_FORMAT_UYVY:
472 case DRM_FORMAT_VYUY:
473 case DRM_FORMAT_YUYV:
474 case DRM_FORMAT_YVYU:
475 return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
476 height, stride);
477
478 case DRM_FORMAT_NV12:
479 case DRM_FORMAT_NV21:
480 case DRM_FORMAT_NV16:
481 case DRM_FORMAT_NV61:
482 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
483 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
484 return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
485 width, height, stride);
486
487 case DRM_FORMAT_YUV420:
488 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
489 planes[2], width, height, stride);
490
491 case DRM_FORMAT_YVU420:
492 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[2],
493 planes[1], width, height, stride);
494
495 case DRM_FORMAT_ARGB4444:
496 case DRM_FORMAT_XRGB4444:
497 case DRM_FORMAT_ABGR4444:
498 case DRM_FORMAT_XBGR4444:
499 case DRM_FORMAT_RGBA4444:
500 case DRM_FORMAT_RGBX4444:
501 case DRM_FORMAT_BGRA4444:
502 case DRM_FORMAT_BGRX4444:
503 case DRM_FORMAT_RGB565:
504 case DRM_FORMAT_BGR565:
505 case DRM_FORMAT_ARGB1555:
506 case DRM_FORMAT_XRGB1555:
507 case DRM_FORMAT_ABGR1555:
508 case DRM_FORMAT_XBGR1555:
509 case DRM_FORMAT_RGBA5551:
510 case DRM_FORMAT_RGBX5551:
511 case DRM_FORMAT_BGRA5551:
512 case DRM_FORMAT_BGRX5551:
513 return fill_smpte_rgb16(&info->rgb, planes[0],
514 width, height, stride);
515
516 case DRM_FORMAT_BGR888:
517 case DRM_FORMAT_RGB888:
518 return fill_smpte_rgb24(&info->rgb, planes[0],
519 width, height, stride);
520 case DRM_FORMAT_ARGB8888:
521 case DRM_FORMAT_XRGB8888:
522 case DRM_FORMAT_ABGR8888:
523 case DRM_FORMAT_XBGR8888:
524 case DRM_FORMAT_RGBA8888:
525 case DRM_FORMAT_RGBX8888:
526 case DRM_FORMAT_BGRA8888:
527 case DRM_FORMAT_BGRX8888:
528 case DRM_FORMAT_ARGB2101010:
529 case DRM_FORMAT_XRGB2101010:
530 case DRM_FORMAT_ABGR2101010:
531 case DRM_FORMAT_XBGR2101010:
532 case DRM_FORMAT_RGBA1010102:
533 case DRM_FORMAT_RGBX1010102:
534 case DRM_FORMAT_BGRA1010102:
535 case DRM_FORMAT_BGRX1010102:
536 return fill_smpte_rgb32(&info->rgb, planes[0],
537 width, height, stride);
538 }
539}
540
541/* swap these for big endian.. */
542#define RED 2
543#define GREEN 1
544#define BLUE 0
545
546static void make_pwetty(void *data, unsigned int width, unsigned int height,
547 unsigned int stride, uint32_t format)
548{
549#ifdef HAVE_CAIRO
550 cairo_surface_t *surface;
551 cairo_t *cr;
552 int x, y;
553 cairo_format_t cairo_format;
554
555 /* we can ignore the order of R,G,B channels */
556 switch (format) {
557 case DRM_FORMAT_XRGB8888:
558 case DRM_FORMAT_ARGB8888:
559 case DRM_FORMAT_XBGR8888:
560 case DRM_FORMAT_ABGR8888:
561 cairo_format = CAIRO_FORMAT_ARGB32;
562 break;
563 case DRM_FORMAT_RGB565:
564 case DRM_FORMAT_BGR565:
565 cairo_format = CAIRO_FORMAT_RGB16_565;
566 break;
567 default:
568 return;
569 }
570
571 surface = cairo_image_surface_create_for_data(data,
572 cairo_format,
573 width, height,
574 stride);
575 cr = cairo_create(surface);
576 cairo_surface_destroy(surface);
577
578 cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
579 for (x = 0; x < width; x += 250)
580 for (y = 0; y < height; y += 250) {
581 char buf[64];
582
583 cairo_move_to(cr, x, y - 20);
584 cairo_line_to(cr, x, y + 20);
585 cairo_move_to(cr, x - 20, y);
586 cairo_line_to(cr, x + 20, y);
587 cairo_new_sub_path(cr);
588 cairo_arc(cr, x, y, 10, 0, M_PI * 2);
589 cairo_set_line_width(cr, 4);
590 cairo_set_source_rgb(cr, 0, 0, 0);
591 cairo_stroke_preserve(cr);
592 cairo_set_source_rgb(cr, 1, 1, 1);
593 cairo_set_line_width(cr, 2);
594 cairo_stroke(cr);
595
596 snprintf(buf, sizeof buf, "%d, %d", x, y);
597 cairo_move_to(cr, x + 20, y + 20);
598 cairo_text_path(cr, buf);
599 cairo_set_source_rgb(cr, 0, 0, 0);
600 cairo_stroke_preserve(cr);
601 cairo_set_source_rgb(cr, 1, 1, 1);
602 cairo_fill(cr);
603 }
604
605 cairo_destroy(cr);
606#endif
607}
608
609static void fill_tiles_yuv_planar(const struct util_format_info *info,
610 unsigned char *y_mem, unsigned char *u_mem,
611 unsigned char *v_mem, unsigned int width,
612 unsigned int height, unsigned int stride)
613{
614 const struct util_yuv_info *yuv = &info->yuv;
615 unsigned int cs = yuv->chroma_stride;
616 unsigned int xsub = yuv->xsub;
617 unsigned int ysub = yuv->ysub;
618 unsigned int x;
619 unsigned int y;
620
621 for (y = 0; y < height; ++y) {
622 for (x = 0; x < width; ++x) {
623 div_t d = div(x+y, width);
624 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
625 + 0x000a1120 * (d.rem >> 6);
626 struct color_yuv color =
627 MAKE_YUV_601((rgb32 >> 16) & 0xff,
628 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
629
630 y_mem[x] = color.y;
631 u_mem[x/xsub*cs] = color.u;
632 v_mem[x/xsub*cs] = color.v;
633 }
634
635 y_mem += stride;
636 if ((y + 1) % ysub == 0) {
637 u_mem += stride * cs / xsub;
638 v_mem += stride * cs / xsub;
639 }
640 }
641}
642
643static void fill_tiles_yuv_packed(const struct util_format_info *info,
644 void *mem, unsigned int width,
645 unsigned int height, unsigned int stride)
646{
647 const struct util_yuv_info *yuv = &info->yuv;
648 unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
649 unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
650 unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
651 unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
652 unsigned int x;
653 unsigned int y;
654
655 for (y = 0; y < height; ++y) {
656 for (x = 0; x < width; x += 2) {
657 div_t d = div(x+y, width);
658 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
659 + 0x000a1120 * (d.rem >> 6);
660 struct color_yuv color =
661 MAKE_YUV_601((rgb32 >> 16) & 0xff,
662 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
663
664 y_mem[2*x] = color.y;
665 c_mem[2*x+u] = color.u;
666 y_mem[2*x+2] = color.y;
667 c_mem[2*x+v] = color.v;
668 }
669
670 y_mem += stride;
671 c_mem += stride;
672 }
673}
674
675static void fill_tiles_rgb16(const struct util_format_info *info, void *mem,
676 unsigned int width, unsigned int height,
677 unsigned int stride)
678{
679 const struct util_rgb_info *rgb = &info->rgb;
680 void *mem_base = mem;
681 unsigned int x, y;
682
683 for (y = 0; y < height; ++y) {
684 for (x = 0; x < width; ++x) {
685 div_t d = div(x+y, width);
686 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
687 + 0x000a1120 * (d.rem >> 6);
688 uint16_t color =
689 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
690 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
691 255);
692
693 ((uint16_t *)mem)[x] = color;
694 }
695 mem += stride;
696 }
697
698 make_pwetty(mem_base, width, height, stride, info->format);
699}
700
701static void fill_tiles_rgb24(const struct util_format_info *info, void *mem,
702 unsigned int width, unsigned int height,
703 unsigned int stride)
704{
705 const struct util_rgb_info *rgb = &info->rgb;
706 unsigned int x, y;
707
708 for (y = 0; y < height; ++y) {
709 for (x = 0; x < width; ++x) {
710 div_t d = div(x+y, width);
711 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
712 + 0x000a1120 * (d.rem >> 6);
713 struct color_rgb24 color =
714 MAKE_RGB24(rgb, (rgb32 >> 16) & 0xff,
715 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
716
717 ((struct color_rgb24 *)mem)[x] = color;
718 }
719 mem += stride;
720 }
721}
722
723static void fill_tiles_rgb32(const struct util_format_info *info, void *mem,
724 unsigned int width, unsigned int height,
725 unsigned int stride)
726{
727 const struct util_rgb_info *rgb = &info->rgb;
728 void *mem_base = mem;
729 unsigned int x, y;
730
731 for (y = 0; y < height; ++y) {
732 for (x = 0; x < width; ++x) {
733 div_t d = div(x+y, width);
734 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
735 + 0x000a1120 * (d.rem >> 6);
736 uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
737 uint32_t color =
738 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
739 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
740 alpha);
741
742 ((uint32_t *)mem)[x] = color;
743 }
744 mem += stride;
745 }
746
747 make_pwetty(mem_base, width, height, stride, info->format);
748}
749
750static void fill_tiles(const struct util_format_info *info, void *planes[3],
751 unsigned int width, unsigned int height,
752 unsigned int stride)
753{
754 unsigned char *u, *v;
755
756 switch (info->format) {
757 case DRM_FORMAT_UYVY:
758 case DRM_FORMAT_VYUY:
759 case DRM_FORMAT_YUYV:
760 case DRM_FORMAT_YVYU:
761 return fill_tiles_yuv_packed(info, planes[0],
762 width, height, stride);
763
764 case DRM_FORMAT_NV12:
765 case DRM_FORMAT_NV21:
766 case DRM_FORMAT_NV16:
767 case DRM_FORMAT_NV61:
768 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
769 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
770 return fill_tiles_yuv_planar(info, planes[0], u, v,
771 width, height, stride);
772
773 case DRM_FORMAT_YUV420:
774 return fill_tiles_yuv_planar(info, planes[0], planes[1],
775 planes[2], width, height, stride);
776
777 case DRM_FORMAT_YVU420:
778 return fill_tiles_yuv_planar(info, planes[0], planes[2],
779 planes[1], width, height, stride);
780
781 case DRM_FORMAT_ARGB4444:
782 case DRM_FORMAT_XRGB4444:
783 case DRM_FORMAT_ABGR4444:
784 case DRM_FORMAT_XBGR4444:
785 case DRM_FORMAT_RGBA4444:
786 case DRM_FORMAT_RGBX4444:
787 case DRM_FORMAT_BGRA4444:
788 case DRM_FORMAT_BGRX4444:
789 case DRM_FORMAT_RGB565:
790 case DRM_FORMAT_BGR565:
791 case DRM_FORMAT_ARGB1555:
792 case DRM_FORMAT_XRGB1555:
793 case DRM_FORMAT_ABGR1555:
794 case DRM_FORMAT_XBGR1555:
795 case DRM_FORMAT_RGBA5551:
796 case DRM_FORMAT_RGBX5551:
797 case DRM_FORMAT_BGRA5551:
798 case DRM_FORMAT_BGRX5551:
799 return fill_tiles_rgb16(info, planes[0],
800 width, height, stride);
801
802 case DRM_FORMAT_BGR888:
803 case DRM_FORMAT_RGB888:
804 return fill_tiles_rgb24(info, planes[0],
805 width, height, stride);
806 case DRM_FORMAT_ARGB8888:
807 case DRM_FORMAT_XRGB8888:
808 case DRM_FORMAT_ABGR8888:
809 case DRM_FORMAT_XBGR8888:
810 case DRM_FORMAT_RGBA8888:
811 case DRM_FORMAT_RGBX8888:
812 case DRM_FORMAT_BGRA8888:
813 case DRM_FORMAT_BGRX8888:
814 case DRM_FORMAT_ARGB2101010:
815 case DRM_FORMAT_XRGB2101010:
816 case DRM_FORMAT_ABGR2101010:
817 case DRM_FORMAT_XBGR2101010:
818 case DRM_FORMAT_RGBA1010102:
819 case DRM_FORMAT_RGBX1010102:
820 case DRM_FORMAT_BGRA1010102:
821 case DRM_FORMAT_BGRX1010102:
822 return fill_tiles_rgb32(info, planes[0],
823 width, height, stride);
824 }
825}
826
827static void fill_plain(const struct util_format_info *info, void *planes[3],
828 unsigned int width, unsigned int height,
829 unsigned int stride)
830{
831 memset(planes[0], 0x77, stride * height);
832}
833
834/*
835 * util_fill_pattern - Fill a buffer with a test pattern
836 * @format: Pixel format
837 * @pattern: Test pattern
838 * @planes: Array of buffers
839 * @width: Width in pixels
840 * @height: Height in pixels
841 * @stride: Line stride (pitch) in bytes
842 *
843 * Fill the buffers with the test pattern specified by the pattern parameter.
844 * Supported formats vary depending on the selected pattern.
845 */
846void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
847 void *planes[3], unsigned int width,
848 unsigned int height, unsigned int stride)
849{
850 const struct util_format_info *info;
851
852 info = util_format_info_find(format);
853 if (info == NULL)
854 return;
855
856 switch (pattern) {
857 case UTIL_PATTERN_TILES:
858 return fill_tiles(info, planes, width, height, stride);
859
860 case UTIL_PATTERN_SMPTE:
861 return fill_smpte(info, planes, width, height, stride);
862
863 case UTIL_PATTERN_PLAIN:
864 return fill_plain(info, planes, width, height, stride);
865
866 default:
867 printf("Error: unsupported test pattern %u.\n", pattern);
868 break;
869 }
870}
diff --git a/tests/util/pattern.h b/tests/util/pattern.h
new file mode 100644
index 00000000..d5c4260c
--- /dev/null
+++ b/tests/util/pattern.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright 2008 Tungsten Graphics
3 * Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25
26#ifndef UTIL_PATTERN_H
27#define UTIL_PATTERN_H
28
29enum util_fill_pattern {
30 UTIL_PATTERN_TILES,
31 UTIL_PATTERN_PLAIN,
32 UTIL_PATTERN_SMPTE,
33};
34
35void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
36 void *planes[3], unsigned int width,
37 unsigned int height, unsigned int stride);
38
39#endif /* UTIL_PATTERN_H */
diff --git a/tests/vbltest/Makefile.am b/tests/vbltest/Makefile.am
index 34a35e7d..276afad5 100644
--- a/tests/vbltest/Makefile.am
+++ b/tests/vbltest/Makefile.am
@@ -1,6 +1,9 @@
1AM_CFLAGS = \ 1AM_CFLAGS = \
2 $(WARN_CFLAGS)\
2 -I$(top_srcdir)/include/drm \ 3 -I$(top_srcdir)/include/drm \
4 -I$(top_srcdir)/tests \
3 -I$(top_srcdir) 5 -I$(top_srcdir)
6
4if HAVE_INSTALL_TESTS 7if HAVE_INSTALL_TESTS
5bin_PROGRAMS = \ 8bin_PROGRAMS = \
6 vbltest 9 vbltest
@@ -12,4 +15,5 @@ endif
12vbltest_SOURCES = \ 15vbltest_SOURCES = \
13 vbltest.c 16 vbltest.c
14vbltest_LDADD = \ 17vbltest_LDADD = \
15 $(top_builddir)/libdrm.la 18 $(top_builddir)/libdrm.la \
19 $(top_builddir)/tests/util/libutil.la
diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c
index cdc1ef6b..18333212 100644
--- a/tests/vbltest/vbltest.c
+++ b/tests/vbltest/vbltest.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * DRM based mode setting test program 2 * DRM based vblank test program
3 * Copyright 2008 Tungsten Graphics 3 * Copyright 2008 Tungsten Graphics
4 * Jakob Bornecrantz <jakob@tungstengraphics.com> 4 * Jakob Bornecrantz <jakob@tungstengraphics.com>
5 * Copyright 2008 Intel Corporation 5 * Copyright 2008 Intel Corporation
@@ -24,19 +24,6 @@
24 * IN THE SOFTWARE. 24 * IN THE SOFTWARE.
25 */ 25 */
26 26
27/*
28 * This fairly simple test program dumps output in a similar format to the
29 * "xrandr" tool everyone knows & loves. It's necessarily slightly different
30 * since the kernel separates outputs into encoder and connector structures,
31 * each with their own unique ID. The program also allows test testing of the
32 * memory management and mode setting APIs by allowing the user to specify a
33 * connector and mode to use for mode setting. If all works as expected, a
34 * blue background should be painted on the monitor attached to the specified
35 * connector after the selected mode is set.
36 *
37 * TODO: use cairo to write the mode info on the selected output once
38 * the mode has been programmed, along with possible test patterns.
39 */
40#ifdef HAVE_CONFIG_H 27#ifdef HAVE_CONFIG_H
41#include "config.h" 28#include "config.h"
42#endif 29#endif
@@ -54,11 +41,12 @@
54#include "xf86drm.h" 41#include "xf86drm.h"
55#include "xf86drmMode.h" 42#include "xf86drmMode.h"
56 43
57#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 44#include "util/common.h"
45#include "util/kms.h"
58 46
59extern char *optarg; 47extern char *optarg;
60extern int optind, opterr, optopt; 48extern int optind, opterr, optopt;
61static char optstr[] = "s"; 49static char optstr[] = "D:M:s";
62 50
63int secondary = 0; 51int secondary = 0;
64 52
@@ -97,15 +85,19 @@ static void vblank_handler(int fd, unsigned int frame, unsigned int sec,
97 85
98static void usage(char *name) 86static void usage(char *name)
99{ 87{
100 fprintf(stderr, "usage: %s [-s]\n", name); 88 fprintf(stderr, "usage: %s [-DMs]\n", name);
101 fprintf(stderr, "\t-s\tuse secondary pipe\n"); 89 fprintf(stderr, "\n");
90 fprintf(stderr, "options:\n");
91 fprintf(stderr, " -D DEVICE open the given device\n");
92 fprintf(stderr, " -M MODULE open the given module\n");
93 fprintf(stderr, " -s use secondary pipe\n");
102 exit(0); 94 exit(0);
103} 95}
104 96
105int main(int argc, char **argv) 97int main(int argc, char **argv)
106{ 98{
107 int i, c, fd, ret; 99 const char *device = NULL, *module = NULL;
108 char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos", "omapdrm", "tilcdc", "msm", "tegra" }; 100 int c, fd, ret;
109 drmVBlank vbl; 101 drmVBlank vbl;
110 drmEventContext evctx; 102 drmEventContext evctx;
111 struct vbl_info handler_info; 103 struct vbl_info handler_info;
@@ -113,6 +105,12 @@ int main(int argc, char **argv)
113 opterr = 0; 105 opterr = 0;
114 while ((c = getopt(argc, argv, optstr)) != -1) { 106 while ((c = getopt(argc, argv, optstr)) != -1) {
115 switch (c) { 107 switch (c) {
108 case 'D':
109 device = optarg;
110 break;
111 case 'M':
112 module = optarg;
113 break;
116 case 's': 114 case 's':
117 secondary = 1; 115 secondary = 1;
118 break; 116 break;
@@ -122,21 +120,9 @@ int main(int argc, char **argv)
122 } 120 }
123 } 121 }
124 122
125 for (i = 0; i < ARRAY_SIZE(modules); i++) { 123 fd = util_open(module, device);
126 printf("trying to load module %s...", modules[i]); 124 if (fd < 0)
127 fd = drmOpen(modules[i], NULL); 125 return 1;
128 if (fd < 0) {
129 printf("failed.\n");
130 } else {
131 printf("success.\n");
132 break;
133 }
134 }
135
136 if (i == ARRAY_SIZE(modules)) {
137 fprintf(stderr, "failed to load any modules, aborting.\n");
138 return -1;
139 }
140 126
141 /* Get current count first */ 127 /* Get current count first */
142 vbl.request.type = DRM_VBLANK_RELATIVE; 128 vbl.request.type = DRM_VBLANK_RELATIVE;
@@ -176,7 +162,6 @@ int main(int argc, char **argv)
176 while (1) { 162 while (1) {
177 struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; 163 struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
178 fd_set fds; 164 fd_set fds;
179 int ret;
180 165
181 FD_ZERO(&fds); 166 FD_ZERO(&fds);
182 FD_SET(0, &fds); 167 FD_SET(0, &fds);
diff --git a/freedreno/list.h b/util_double_list.h
index 27e0761b..27e0761b 100644
--- a/freedreno/list.h
+++ b/util_double_list.h
diff --git a/util_math.h b/util_math.h
new file mode 100644
index 00000000..02b15a8e
--- /dev/null
+++ b/util_math.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22*/
23
24#ifndef _UTIL_MATH_H_
25#define _UTIL_MATH_H_
26
27#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
28#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
29#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C))
30
31#define __align_mask(value, mask) (((value) + (mask)) & ~(mask))
32#define ALIGN(value, alignment) __align_mask(value, (typeof(value))((alignment) - 1))
33
34#endif /*_UTIL_MATH_H_*/
diff --git a/xf86atomic.h b/xf86atomic.h
index bc482c92..922b37da 100644
--- a/xf86atomic.h
+++ b/xf86atomic.h
@@ -49,7 +49,8 @@ typedef struct {
49# define atomic_read(x) ((x)->atomic) 49# define atomic_read(x) ((x)->atomic)
50# define atomic_set(x, val) ((x)->atomic = (val)) 50# define atomic_set(x, val) ((x)->atomic = (val))
51# define atomic_inc(x) ((void) __sync_fetch_and_add (&(x)->atomic, 1)) 51# define atomic_inc(x) ((void) __sync_fetch_and_add (&(x)->atomic, 1))
52# define atomic_dec_and_test(x) (__sync_fetch_and_add (&(x)->atomic, -1) == 1) 52# define atomic_inc_return(x) (__sync_add_and_fetch (&(x)->atomic, 1))
53# define atomic_dec_and_test(x) (__sync_add_and_fetch (&(x)->atomic, -1) == 0)
53# define atomic_add(x, v) ((void) __sync_add_and_fetch(&(x)->atomic, (v))) 54# define atomic_add(x, v) ((void) __sync_add_and_fetch(&(x)->atomic, (v)))
54# define atomic_dec(x, v) ((void) __sync_sub_and_fetch(&(x)->atomic, (v))) 55# define atomic_dec(x, v) ((void) __sync_sub_and_fetch(&(x)->atomic, (v)))
55# define atomic_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (&(x)->atomic, oldv, newv) 56# define atomic_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (&(x)->atomic, oldv, newv)
@@ -68,6 +69,7 @@ typedef struct {
68# define atomic_read(x) AO_load_full(&(x)->atomic) 69# define atomic_read(x) AO_load_full(&(x)->atomic)
69# define atomic_set(x, val) AO_store_full(&(x)->atomic, (val)) 70# define atomic_set(x, val) AO_store_full(&(x)->atomic, (val))
70# define atomic_inc(x) ((void) AO_fetch_and_add1_full(&(x)->atomic)) 71# define atomic_inc(x) ((void) AO_fetch_and_add1_full(&(x)->atomic))
72# define atomic_inc_return(x) (AO_fetch_and_add1_full(&(x)->atomic) + 1)
71# define atomic_add(x, v) ((void) AO_fetch_and_add_full(&(x)->atomic, (v))) 73# define atomic_add(x, v) ((void) AO_fetch_and_add_full(&(x)->atomic, (v)))
72# define atomic_dec(x, v) ((void) AO_fetch_and_add_full(&(x)->atomic, -(v))) 74# define atomic_dec(x, v) ((void) AO_fetch_and_add_full(&(x)->atomic, -(v)))
73# define atomic_dec_and_test(x) (AO_fetch_and_sub1_full(&(x)->atomic) == 1) 75# define atomic_dec_and_test(x) (AO_fetch_and_sub1_full(&(x)->atomic) == 1)
@@ -75,17 +77,24 @@ typedef struct {
75 77
76#endif 78#endif
77 79
78#if defined(__sun) && !defined(HAS_ATOMIC_OPS) /* Solaris & OpenSolaris */ 80#if (defined(__sun) || defined(__NetBSD__)) && !defined(HAS_ATOMIC_OPS) /* Solaris & OpenSolaris & NetBSD */
79 81
80#include <sys/atomic.h> 82#include <sys/atomic.h>
81#define HAS_ATOMIC_OPS 1 83#define HAS_ATOMIC_OPS 1
82 84
83typedef struct { uint_t atomic; } atomic_t; 85#if defined(__NetBSD__)
86#define LIBDRM_ATOMIC_TYPE int
87#else
88#define LIBDRM_ATOMIC_TYPE uint_t
89#endif
90
91typedef struct { LIBDRM_ATOMIC_TYPE atomic; } atomic_t;
84 92
85# define atomic_read(x) (int) ((x)->atomic) 93# define atomic_read(x) (int) ((x)->atomic)
86# define atomic_set(x, val) ((x)->atomic = (uint_t)(val)) 94# define atomic_set(x, val) ((x)->atomic = (LIBDRM_ATOMIC_TYPE)(val))
87# define atomic_inc(x) (atomic_inc_uint (&(x)->atomic)) 95# define atomic_inc(x) (atomic_inc_uint (&(x)->atomic))
88# define atomic_dec_and_test(x) (atomic_dec_uint_nv(&(x)->atomic) == 1) 96# define atomic_inc_return(x) (atomic_inc_uint_nv(&(x)->atomic))
97# define atomic_dec_and_test(x) (atomic_dec_uint_nv(&(x)->atomic) == 0)
89# define atomic_add(x, v) (atomic_add_int(&(x)->atomic, (v))) 98# define atomic_add(x, v) (atomic_add_int(&(x)->atomic, (v)))
90# define atomic_dec(x, v) (atomic_add_int(&(x)->atomic, -(v))) 99# define atomic_dec(x, v) (atomic_add_int(&(x)->atomic, -(v)))
91# define atomic_cmpxchg(x, oldv, newv) atomic_cas_uint (&(x)->atomic, oldv, newv) 100# define atomic_cmpxchg(x, oldv, newv) atomic_cas_uint (&(x)->atomic, oldv, newv)
diff --git a/xf86drm.c b/xf86drm.c
index d900b4bd..7e28b4f7 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -36,12 +36,16 @@
36#endif 36#endif
37#include <stdio.h> 37#include <stdio.h>
38#include <stdlib.h> 38#include <stdlib.h>
39#include <stdbool.h>
39#include <unistd.h> 40#include <unistd.h>
40#include <string.h> 41#include <string.h>
41#include <strings.h> 42#include <strings.h>
42#include <ctype.h> 43#include <ctype.h>
44#include <dirent.h>
45#include <stddef.h>
43#include <fcntl.h> 46#include <fcntl.h>
44#include <errno.h> 47#include <errno.h>
48#include <limits.h>
45#include <signal.h> 49#include <signal.h>
46#include <time.h> 50#include <time.h>
47#include <sys/types.h> 51#include <sys/types.h>
@@ -50,6 +54,10 @@
50#include <sys/ioctl.h> 54#include <sys/ioctl.h>
51#include <sys/time.h> 55#include <sys/time.h>
52#include <stdarg.h> 56#include <stdarg.h>
57#ifdef HAVE_SYS_MKDEV_H
58# include <sys/mkdev.h> /* defines major(), minor(), and makedev() on Solaris */
59#endif
60#include <math.h>
53 61
54/* Not all systems have MAP_FAILED defined */ 62/* Not all systems have MAP_FAILED defined */
55#ifndef MAP_FAILED 63#ifndef MAP_FAILED
@@ -57,7 +65,19 @@
57#endif 65#endif
58 66
59#include "xf86drm.h" 67#include "xf86drm.h"
60#include "libdrm.h" 68#include "libdrm_macros.h"
69
70#include "util_math.h"
71
72#ifdef __OpenBSD__
73#define DRM_PRIMARY_MINOR_NAME "drm"
74#define DRM_CONTROL_MINOR_NAME "drmC"
75#define DRM_RENDER_MINOR_NAME "drmR"
76#else
77#define DRM_PRIMARY_MINOR_NAME "card"
78#define DRM_CONTROL_MINOR_NAME "controlD"
79#define DRM_RENDER_MINOR_NAME "renderD"
80#endif
61 81
62#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 82#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
63#define DRM_MAJOR 145 83#define DRM_MAJOR 145
@@ -67,26 +87,21 @@
67#define DRM_MAJOR 34 87#define DRM_MAJOR 34
68#endif 88#endif
69 89
70# ifdef __OpenBSD__ 90#ifdef __OpenBSD__
71# define DRM_MAJOR 81 91#ifdef __i386__
72# endif 92#define DRM_MAJOR 88
93#else
94#define DRM_MAJOR 87
95#endif
96#endif /* __OpenBSD__ */
73 97
74#ifndef DRM_MAJOR 98#ifndef DRM_MAJOR
75#define DRM_MAJOR 226 /* Linux */ 99#define DRM_MAJOR 226 /* Linux */
76#endif 100#endif
77 101
78/*
79 * This definition needs to be changed on some systems if dev_t is a structure.
80 * If there is a header file we can get it from, there would be best.
81 */
82#ifndef makedev
83#define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
84#endif
85
86#define DRM_MSG_VERBOSITY 3 102#define DRM_MSG_VERBOSITY 3
87 103
88#define DRM_NODE_CONTROL 0 104#define memclear(s) memset(&s, 0, sizeof(s))
89#define DRM_NODE_RENDER 1
90 105
91static drmServerInfoPtr drm_server_info; 106static drmServerInfoPtr drm_server_info;
92 107
@@ -110,34 +125,24 @@ drmDebugPrint(const char *format, va_list ap)
110 return vfprintf(stderr, format, ap); 125 return vfprintf(stderr, format, ap);
111} 126}
112 127
113typedef int DRM_PRINTFLIKE(1, 0) (*debug_msg_func_t)(const char *format,
114 va_list ap);
115
116static debug_msg_func_t drm_debug_print = drmDebugPrint;
117
118void 128void
119drmMsg(const char *format, ...) 129drmMsg(const char *format, ...)
120{ 130{
121 va_list ap; 131 va_list ap;
122 const char *env; 132 const char *env;
123 if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || drm_server_info) 133 if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) ||
134 (drm_server_info && drm_server_info->debug_print))
124 { 135 {
125 va_start(ap, format); 136 va_start(ap, format);
126 if (drm_server_info) { 137 if (drm_server_info) {
127 drm_server_info->debug_print(format,ap); 138 drm_server_info->debug_print(format,ap);
128 } else { 139 } else {
129 drm_debug_print(format, ap); 140 drmDebugPrint(format, ap);
130 } 141 }
131 va_end(ap); 142 va_end(ap);
132 } 143 }
133} 144}
134 145
135void
136drmSetDebugMsgFunction(debug_msg_func_t debug_msg_ptr)
137{
138 drm_debug_print = debug_msg_ptr;
139}
140
141static void *drmHashTable = NULL; /* Context switch callbacks */ 146static void *drmHashTable = NULL; /* Context switch callbacks */
142 147
143void *drmGetHashTable(void) 148void *drmGetHashTable(void)
@@ -147,16 +152,12 @@ void *drmGetHashTable(void)
147 152
148void *drmMalloc(int size) 153void *drmMalloc(int size)
149{ 154{
150 void *pt; 155 return calloc(1, size);
151 if ((pt = malloc(size)))
152 memset(pt, 0, size);
153 return pt;
154} 156}
155 157
156void drmFree(void *pt) 158void drmFree(void *pt)
157{ 159{
158 if (pt) 160 free(pt);
159 free(pt);
160} 161}
161 162
162/** 163/**
@@ -273,6 +274,7 @@ static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
273 * If any other failure happened then it will output error mesage using 274 * If any other failure happened then it will output error mesage using
274 * drmMsg() call. 275 * drmMsg() call.
275 */ 276 */
277#if !defined(UDEV)
276static int chown_check_return(const char *path, uid_t owner, gid_t group) 278static int chown_check_return(const char *path, uid_t owner, gid_t group)
277{ 279{
278 int rv; 280 int rv;
@@ -288,6 +290,7 @@ static int chown_check_return(const char *path, uid_t owner, gid_t group)
288 path, errno, strerror(errno)); 290 path, errno, strerror(errno));
289 return -1; 291 return -1;
290} 292}
293#endif
291 294
292/** 295/**
293 * Open the DRM device, creating it if necessary. 296 * Open the DRM device, creating it if necessary.
@@ -302,24 +305,41 @@ static int chown_check_return(const char *path, uid_t owner, gid_t group)
302 * special file node with the major and minor numbers specified by \p dev and 305 * special file node with the major and minor numbers specified by \p dev and
303 * parent directory if necessary and was called by root. 306 * parent directory if necessary and was called by root.
304 */ 307 */
305static int drmOpenDevice(long dev, int minor, int type) 308static int drmOpenDevice(dev_t dev, int minor, int type)
306{ 309{
307 stat_t st; 310 stat_t st;
311 const char *dev_name;
308 char buf[64]; 312 char buf[64];
309 int fd; 313 int fd;
310 mode_t devmode = DRM_DEV_MODE, serv_mode; 314 mode_t devmode = DRM_DEV_MODE, serv_mode;
315 gid_t serv_group;
316#if !defined(UDEV)
311 int isroot = !geteuid(); 317 int isroot = !geteuid();
312 uid_t user = DRM_DEV_UID; 318 uid_t user = DRM_DEV_UID;
313 gid_t group = DRM_DEV_GID, serv_group; 319 gid_t group = DRM_DEV_GID;
314 320#endif
315 sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor); 321
322 switch (type) {
323 case DRM_NODE_PRIMARY:
324 dev_name = DRM_DEV_NAME;
325 break;
326 case DRM_NODE_CONTROL:
327 dev_name = DRM_CONTROL_DEV_NAME;
328 break;
329 case DRM_NODE_RENDER:
330 dev_name = DRM_RENDER_DEV_NAME;
331 break;
332 default:
333 return -EINVAL;
334 };
335
336 sprintf(buf, dev_name, DRM_DIR_NAME, minor);
316 drmMsg("drmOpenDevice: node name is %s\n", buf); 337 drmMsg("drmOpenDevice: node name is %s\n", buf);
317 338
318 if (drm_server_info) { 339 if (drm_server_info && drm_server_info->get_perms) {
319 drm_server_info->get_perms(&serv_group, &serv_mode); 340 drm_server_info->get_perms(&serv_group, &serv_mode);
320 devmode = serv_mode ? serv_mode : DRM_DEV_MODE; 341 devmode = serv_mode ? serv_mode : DRM_DEV_MODE;
321 devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); 342 devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
322 group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
323 } 343 }
324 344
325#if !defined(UDEV) 345#if !defined(UDEV)
@@ -339,7 +359,8 @@ static int drmOpenDevice(long dev, int minor, int type)
339 mknod(buf, S_IFCHR | devmode, dev); 359 mknod(buf, S_IFCHR | devmode, dev);
340 } 360 }
341 361
342 if (drm_server_info) { 362 if (drm_server_info && drm_server_info->get_perms) {
363 group = ((int)serv_group >= 0) ? serv_group : DRM_DEV_GID;
343 chown_check_return(buf, user, group); 364 chown_check_return(buf, user, group);
344 chmod(buf, devmode); 365 chmod(buf, devmode);
345 } 366 }
@@ -383,7 +404,7 @@ wait_for_udev:
383 return DRM_ERR_NOT_ROOT; 404 return DRM_ERR_NOT_ROOT;
384 remove(buf); 405 remove(buf);
385 mknod(buf, S_IFCHR | devmode, dev); 406 mknod(buf, S_IFCHR | devmode, dev);
386 if (drm_server_info) { 407 if (drm_server_info && drm_server_info->get_perms) {
387 chown_check_return(buf, user, group); 408 chown_check_return(buf, user, group);
388 chmod(buf, devmode); 409 chmod(buf, devmode);
389 } 410 }
@@ -417,11 +438,26 @@ static int drmOpenMinor(int minor, int create, int type)
417{ 438{
418 int fd; 439 int fd;
419 char buf[64]; 440 char buf[64];
441 const char *dev_name;
420 442
421 if (create) 443 if (create)
422 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type); 444 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
423 445
424 sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor); 446 switch (type) {
447 case DRM_NODE_PRIMARY:
448 dev_name = DRM_DEV_NAME;
449 break;
450 case DRM_NODE_CONTROL:
451 dev_name = DRM_CONTROL_DEV_NAME;
452 break;
453 case DRM_NODE_RENDER:
454 dev_name = DRM_RENDER_DEV_NAME;
455 break;
456 default:
457 return -EINVAL;
458 };
459
460 sprintf(buf, dev_name, DRM_DIR_NAME, minor);
425 if ((fd = open(buf, O_RDWR, 0)) >= 0) 461 if ((fd = open(buf, O_RDWR, 0)) >= 0)
426 return fd; 462 return fd;
427 return -errno; 463 return -errno;
@@ -444,7 +480,7 @@ int drmAvailable(void)
444 int retval = 0; 480 int retval = 0;
445 int fd; 481 int fd;
446 482
447 if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) { 483 if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) {
448#ifdef __linux__ 484#ifdef __linux__
449 /* Try proc for backward Linux compatibility */ 485 /* Try proc for backward Linux compatibility */
450 if (!access("/proc/dri/0", R_OK)) 486 if (!access("/proc/dri/0", R_OK))
@@ -462,11 +498,56 @@ int drmAvailable(void)
462 return retval; 498 return retval;
463} 499}
464 500
501static int drmGetMinorBase(int type)
502{
503 switch (type) {
504 case DRM_NODE_PRIMARY:
505 return 0;
506 case DRM_NODE_CONTROL:
507 return 64;
508 case DRM_NODE_RENDER:
509 return 128;
510 default:
511 return -1;
512 };
513}
514
515static int drmGetMinorType(int minor)
516{
517 int type = minor >> 6;
518
519 if (minor < 0)
520 return -1;
521
522 switch (type) {
523 case DRM_NODE_PRIMARY:
524 case DRM_NODE_CONTROL:
525 case DRM_NODE_RENDER:
526 return type;
527 default:
528 return -1;
529 }
530}
531
532static const char *drmGetMinorName(int type)
533{
534 switch (type) {
535 case DRM_NODE_PRIMARY:
536 return DRM_PRIMARY_MINOR_NAME;
537 case DRM_NODE_CONTROL:
538 return DRM_CONTROL_MINOR_NAME;
539 case DRM_NODE_RENDER:
540 return DRM_RENDER_MINOR_NAME;
541 default:
542 return NULL;
543 }
544}
465 545
466/** 546/**
467 * Open the device by bus ID. 547 * Open the device by bus ID.
468 * 548 *
469 * \param busid bus ID. 549 * \param busid bus ID.
550 * \param type device node type.
470 * 551 *
471 * \return a file descriptor on success, or a negative value on error. 552 * \return a file descriptor on success, or a negative value on error.
472 * 553 *
@@ -476,16 +557,20 @@ int drmAvailable(void)
476 * 557 *
477 * \sa drmOpenMinor() and drmGetBusid(). 558 * \sa drmOpenMinor() and drmGetBusid().
478 */ 559 */
479static int drmOpenByBusid(const char *busid) 560static int drmOpenByBusid(const char *busid, int type)
480{ 561{
481 int i, pci_domain_ok = 1; 562 int i, pci_domain_ok = 1;
482 int fd; 563 int fd;
483 const char *buf; 564 const char *buf;
484 drmSetVersion sv; 565 drmSetVersion sv;
566 int base = drmGetMinorBase(type);
567
568 if (base < 0)
569 return -1;
485 570
486 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid); 571 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
487 for (i = 0; i < DRM_MAX_MINOR; i++) { 572 for (i = base; i < base + DRM_MAX_MINOR; i++) {
488 fd = drmOpenMinor(i, 1, DRM_NODE_RENDER); 573 fd = drmOpenMinor(i, 1, type);
489 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); 574 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
490 if (fd >= 0) { 575 if (fd >= 0) {
491 /* We need to try for 1.4 first for proper PCI domain support 576 /* We need to try for 1.4 first for proper PCI domain support
@@ -525,6 +610,7 @@ static int drmOpenByBusid(const char *busid)
525 * Open the device by name. 610 * Open the device by name.
526 * 611 *
527 * \param name driver name. 612 * \param name driver name.
613 * \param type the device node type.
528 * 614 *
529 * \return a file descriptor on success, or a negative value on error. 615 * \return a file descriptor on success, or a negative value on error.
530 * 616 *
@@ -535,19 +621,23 @@ static int drmOpenByBusid(const char *busid)
535 * 621 *
536 * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid(). 622 * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
537 */ 623 */
538static int drmOpenByName(const char *name) 624static int drmOpenByName(const char *name, int type)
539{ 625{
540 int i; 626 int i;
541 int fd; 627 int fd;
542 drmVersionPtr version; 628 drmVersionPtr version;
543 char * id; 629 char * id;
630 int base = drmGetMinorBase(type);
631
632 if (base < 0)
633 return -1;
544 634
545 /* 635 /*
546 * Open the first minor number that matches the driver name and isn't 636 * Open the first minor number that matches the driver name and isn't
547 * already in use. If it's in use it will have a busid assigned already. 637 * already in use. If it's in use it will have a busid assigned already.
548 */ 638 */
549 for (i = 0; i < DRM_MAX_MINOR; i++) { 639 for (i = base; i < base + DRM_MAX_MINOR; i++) {
550 if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) { 640 if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
551 if ((version = drmGetVersion(fd))) { 641 if ((version = drmGetVersion(fd))) {
552 if (!strcmp(version->name, name)) { 642 if (!strcmp(version->name, name)) {
553 drmFreeVersion(version); 643 drmFreeVersion(version);
@@ -589,9 +679,9 @@ static int drmOpenByName(const char *name)
589 for (devstring = ++pt; *pt && *pt != ' '; ++pt) 679 for (devstring = ++pt; *pt && *pt != ' '; ++pt)
590 ; 680 ;
591 if (*pt) { /* Found busid */ 681 if (*pt) { /* Found busid */
592 return drmOpenByBusid(++pt); 682 return drmOpenByBusid(++pt, type);
593 } else { /* No busid */ 683 } else { /* No busid */
594 return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER); 684 return drmOpenDevice(strtol(devstring, NULL, 0),i, type);
595 } 685 }
596 } 686 }
597 } 687 }
@@ -621,8 +711,30 @@ static int drmOpenByName(const char *name)
621 */ 711 */
622int drmOpen(const char *name, const char *busid) 712int drmOpen(const char *name, const char *busid)
623{ 713{
624 if (!drmAvailable() && name != NULL && drm_server_info) { 714 return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
625 /* try to load the kernel */ 715}
716
717/**
718 * Open the DRM device with specified type.
719 *
720 * Looks up the specified name and bus ID, and opens the device found. The
721 * entry in /dev/dri is created if necessary and if called by root.
722 *
723 * \param name driver name. Not referenced if bus ID is supplied.
724 * \param busid bus ID. Zero if not known.
725 * \param type the device node type to open, PRIMARY, CONTROL or RENDER
726 *
727 * \return a file descriptor on success, or a negative value on error.
728 *
729 * \internal
730 * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
731 * otherwise.
732 */
733int drmOpenWithType(const char *name, const char *busid, int type)
734{
735 if (!drmAvailable() && name != NULL && drm_server_info &&
736 drm_server_info->load_module) {
737 /* try to load the kernel module */
626 if (!drm_server_info->load_module(name)) { 738 if (!drm_server_info->load_module(name)) {
627 drmMsg("[drm] failed to load kernel module \"%s\"\n", name); 739 drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
628 return -1; 740 return -1;
@@ -630,13 +742,13 @@ int drmOpen(const char *name, const char *busid)
630 } 742 }
631 743
632 if (busid) { 744 if (busid) {
633 int fd = drmOpenByBusid(busid); 745 int fd = drmOpenByBusid(busid, type);
634 if (fd >= 0) 746 if (fd >= 0)
635 return fd; 747 return fd;
636 } 748 }
637 749
638 if (name) 750 if (name)
639 return drmOpenByName(name); 751 return drmOpenByName(name, type);
640 752
641 return -1; 753 return -1;
642} 754}
@@ -646,6 +758,11 @@ int drmOpenControl(int minor)
646 return drmOpenMinor(minor, 0, DRM_NODE_CONTROL); 758 return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
647} 759}
648 760
761int drmOpenRender(int minor)
762{
763 return drmOpenMinor(minor, 0, DRM_NODE_RENDER);
764}
765
649/** 766/**
650 * Free the version information returned by drmGetVersion(). 767 * Free the version information returned by drmGetVersion().
651 * 768 *
@@ -730,12 +847,7 @@ drmVersionPtr drmGetVersion(int fd)
730 drmVersionPtr retval; 847 drmVersionPtr retval;
731 drm_version_t *version = drmMalloc(sizeof(*version)); 848 drm_version_t *version = drmMalloc(sizeof(*version));
732 849
733 version->name_len = 0; 850 memclear(*version);
734 version->name = NULL;
735 version->date_len = 0;
736 version->date = NULL;
737 version->desc_len = 0;
738 version->desc = NULL;
739 851
740 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) { 852 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
741 drmFreeKernelVersion(version); 853 drmFreeKernelVersion(version);
@@ -803,9 +915,12 @@ drmVersionPtr drmGetLibVersion(int fd)
803 915
804int drmGetCap(int fd, uint64_t capability, uint64_t *value) 916int drmGetCap(int fd, uint64_t capability, uint64_t *value)
805{ 917{
806 struct drm_get_cap cap = { capability, 0 }; 918 struct drm_get_cap cap;
807 int ret; 919 int ret;
808 920
921 memclear(cap);
922 cap.capability = capability;
923
809 ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap); 924 ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
810 if (ret) 925 if (ret)
811 return ret; 926 return ret;
@@ -816,7 +931,11 @@ int drmGetCap(int fd, uint64_t capability, uint64_t *value)
816 931
817int drmSetClientCap(int fd, uint64_t capability, uint64_t value) 932int drmSetClientCap(int fd, uint64_t capability, uint64_t value)
818{ 933{
819 struct drm_set_client_cap cap = { capability, value }; 934 struct drm_set_client_cap cap;
935
936 memclear(cap);
937 cap.capability = capability;
938 cap.value = value;
820 939
821 return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap); 940 return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap);
822} 941}
@@ -851,8 +970,7 @@ char *drmGetBusid(int fd)
851{ 970{
852 drm_unique_t u; 971 drm_unique_t u;
853 972
854 u.unique_len = 0; 973 memclear(u);
855 u.unique = NULL;
856 974
857 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) 975 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
858 return NULL; 976 return NULL;
@@ -881,6 +999,7 @@ int drmSetBusid(int fd, const char *busid)
881{ 999{
882 drm_unique_t u; 1000 drm_unique_t u;
883 1001
1002 memclear(u);
884 u.unique = (char *)busid; 1003 u.unique = (char *)busid;
885 u.unique_len = strlen(busid); 1004 u.unique_len = strlen(busid);
886 1005
@@ -894,6 +1013,8 @@ int drmGetMagic(int fd, drm_magic_t * magic)
894{ 1013{
895 drm_auth_t auth; 1014 drm_auth_t auth;
896 1015
1016 memclear(auth);
1017
897 *magic = 0; 1018 *magic = 0;
898 if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) 1019 if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
899 return -errno; 1020 return -errno;
@@ -905,6 +1026,7 @@ int drmAuthMagic(int fd, drm_magic_t magic)
905{ 1026{
906 drm_auth_t auth; 1027 drm_auth_t auth;
907 1028
1029 memclear(auth);
908 auth.magic = magic; 1030 auth.magic = magic;
909 if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) 1031 if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
910 return -errno; 1032 return -errno;
@@ -966,9 +1088,9 @@ int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
966{ 1088{
967 drm_map_t map; 1089 drm_map_t map;
968 1090
1091 memclear(map);
969 map.offset = offset; 1092 map.offset = offset;
970 map.size = size; 1093 map.size = size;
971 map.handle = 0;
972 map.type = type; 1094 map.type = type;
973 map.flags = flags; 1095 map.flags = flags;
974 if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map)) 1096 if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
@@ -982,6 +1104,7 @@ int drmRmMap(int fd, drm_handle_t handle)
982{ 1104{
983 drm_map_t map; 1105 drm_map_t map;
984 1106
1107 memclear(map);
985 map.handle = (void *)(uintptr_t)handle; 1108 map.handle = (void *)(uintptr_t)handle;
986 1109
987 if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map)) 1110 if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
@@ -1010,10 +1133,9 @@ int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
1010{ 1133{
1011 drm_buf_desc_t request; 1134 drm_buf_desc_t request;
1012 1135
1136 memclear(request);
1013 request.count = count; 1137 request.count = count;
1014 request.size = size; 1138 request.size = size;
1015 request.low_mark = 0;
1016 request.high_mark = 0;
1017 request.flags = flags; 1139 request.flags = flags;
1018 request.agp_start = agp_offset; 1140 request.agp_start = agp_offset;
1019 1141
@@ -1027,8 +1149,7 @@ int drmMarkBufs(int fd, double low, double high)
1027 drm_buf_info_t info; 1149 drm_buf_info_t info;
1028 int i; 1150 int i;
1029 1151
1030 info.count = 0; 1152 memclear(info);
1031 info.list = NULL;
1032 1153
1033 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 1154 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1034 return -EINVAL; 1155 return -EINVAL;
@@ -1078,6 +1199,7 @@ int drmFreeBufs(int fd, int count, int *list)
1078{ 1199{
1079 drm_buf_free_t request; 1200 drm_buf_free_t request;
1080 1201
1202 memclear(request);
1081 request.count = count; 1203 request.count = count;
1082 request.list = list; 1204 request.list = list;
1083 if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request)) 1205 if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
@@ -1166,8 +1288,7 @@ drmBufInfoPtr drmGetBufInfo(int fd)
1166 drmBufInfoPtr retval; 1288 drmBufInfoPtr retval;
1167 int i; 1289 int i;
1168 1290
1169 info.count = 0; 1291 memclear(info);
1170 info.list = NULL;
1171 1292
1172 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 1293 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1173 return NULL; 1294 return NULL;
@@ -1217,9 +1338,7 @@ drmBufMapPtr drmMapBufs(int fd)
1217 drmBufMapPtr retval; 1338 drmBufMapPtr retval;
1218 int i; 1339 int i;
1219 1340
1220 bufs.count = 0; 1341 memclear(bufs);
1221 bufs.list = NULL;
1222 bufs.virtual = NULL;
1223 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) 1342 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
1224 return NULL; 1343 return NULL;
1225 1344
@@ -1335,6 +1454,7 @@ int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1335{ 1454{
1336 drm_lock_t lock; 1455 drm_lock_t lock;
1337 1456
1457 memclear(lock);
1338 lock.context = context; 1458 lock.context = context;
1339 lock.flags = 0; 1459 lock.flags = 0;
1340 if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; 1460 if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
@@ -1365,8 +1485,8 @@ int drmUnlock(int fd, drm_context_t context)
1365{ 1485{
1366 drm_lock_t lock; 1486 drm_lock_t lock;
1367 1487
1488 memclear(lock);
1368 lock.context = context; 1489 lock.context = context;
1369 lock.flags = 0;
1370 return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock); 1490 return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
1371} 1491}
1372 1492
@@ -1377,8 +1497,7 @@ drm_context_t *drmGetReservedContextList(int fd, int *count)
1377 drm_context_t * retval; 1497 drm_context_t * retval;
1378 int i; 1498 int i;
1379 1499
1380 res.count = 0; 1500 memclear(res);
1381 res.contexts = NULL;
1382 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 1501 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1383 return NULL; 1502 return NULL;
1384 1503
@@ -1431,7 +1550,7 @@ int drmCreateContext(int fd, drm_context_t *handle)
1431{ 1550{
1432 drm_ctx_t ctx; 1551 drm_ctx_t ctx;
1433 1552
1434 ctx.flags = 0; /* Modified with functions below */ 1553 memclear(ctx);
1435 if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) 1554 if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
1436 return -errno; 1555 return -errno;
1437 *handle = ctx.handle; 1556 *handle = ctx.handle;
@@ -1442,6 +1561,7 @@ int drmSwitchToContext(int fd, drm_context_t context)
1442{ 1561{
1443 drm_ctx_t ctx; 1562 drm_ctx_t ctx;
1444 1563
1564 memclear(ctx);
1445 ctx.handle = context; 1565 ctx.handle = context;
1446 if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) 1566 if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
1447 return -errno; 1567 return -errno;
@@ -1458,8 +1578,8 @@ int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
1458 * X server (which promises to maintain hardware context), or in the 1578 * X server (which promises to maintain hardware context), or in the
1459 * client-side library when buffers are swapped on behalf of two threads. 1579 * client-side library when buffers are swapped on behalf of two threads.
1460 */ 1580 */
1581 memclear(ctx);
1461 ctx.handle = context; 1582 ctx.handle = context;
1462 ctx.flags = 0;
1463 if (flags & DRM_CONTEXT_PRESERVED) 1583 if (flags & DRM_CONTEXT_PRESERVED)
1464 ctx.flags |= _DRM_CONTEXT_PRESERVED; 1584 ctx.flags |= _DRM_CONTEXT_PRESERVED;
1465 if (flags & DRM_CONTEXT_2DONLY) 1585 if (flags & DRM_CONTEXT_2DONLY)
@@ -1474,6 +1594,7 @@ int drmGetContextFlags(int fd, drm_context_t context,
1474{ 1594{
1475 drm_ctx_t ctx; 1595 drm_ctx_t ctx;
1476 1596
1597 memclear(ctx);
1477 ctx.handle = context; 1598 ctx.handle = context;
1478 if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx)) 1599 if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
1479 return -errno; 1600 return -errno;
@@ -1505,6 +1626,8 @@ int drmGetContextFlags(int fd, drm_context_t context,
1505int drmDestroyContext(int fd, drm_context_t handle) 1626int drmDestroyContext(int fd, drm_context_t handle)
1506{ 1627{
1507 drm_ctx_t ctx; 1628 drm_ctx_t ctx;
1629
1630 memclear(ctx);
1508 ctx.handle = handle; 1631 ctx.handle = handle;
1509 if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx)) 1632 if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
1510 return -errno; 1633 return -errno;
@@ -1514,6 +1637,8 @@ int drmDestroyContext(int fd, drm_context_t handle)
1514int drmCreateDrawable(int fd, drm_drawable_t *handle) 1637int drmCreateDrawable(int fd, drm_drawable_t *handle)
1515{ 1638{
1516 drm_draw_t draw; 1639 drm_draw_t draw;
1640
1641 memclear(draw);
1517 if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) 1642 if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
1518 return -errno; 1643 return -errno;
1519 *handle = draw.handle; 1644 *handle = draw.handle;
@@ -1523,6 +1648,8 @@ int drmCreateDrawable(int fd, drm_drawable_t *handle)
1523int drmDestroyDrawable(int fd, drm_drawable_t handle) 1648int drmDestroyDrawable(int fd, drm_drawable_t handle)
1524{ 1649{
1525 drm_draw_t draw; 1650 drm_draw_t draw;
1651
1652 memclear(draw);
1526 draw.handle = handle; 1653 draw.handle = handle;
1527 if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw)) 1654 if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
1528 return -errno; 1655 return -errno;
@@ -1535,6 +1662,7 @@ int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
1535{ 1662{
1536 drm_update_draw_t update; 1663 drm_update_draw_t update;
1537 1664
1665 memclear(update);
1538 update.handle = handle; 1666 update.handle = handle;
1539 update.type = type; 1667 update.type = type;
1540 update.num = num; 1668 update.num = num;
@@ -1600,6 +1728,7 @@ int drmAgpEnable(int fd, unsigned long mode)
1600{ 1728{
1601 drm_agp_mode_t m; 1729 drm_agp_mode_t m;
1602 1730
1731 memclear(m);
1603 m.mode = mode; 1732 m.mode = mode;
1604 if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) 1733 if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
1605 return -errno; 1734 return -errno;
@@ -1628,9 +1757,9 @@ int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
1628{ 1757{
1629 drm_agp_buffer_t b; 1758 drm_agp_buffer_t b;
1630 1759
1760 memclear(b);
1631 *handle = DRM_AGP_NO_HANDLE; 1761 *handle = DRM_AGP_NO_HANDLE;
1632 b.size = size; 1762 b.size = size;
1633 b.handle = 0;
1634 b.type = type; 1763 b.type = type;
1635 if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) 1764 if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
1636 return -errno; 1765 return -errno;
@@ -1657,7 +1786,7 @@ int drmAgpFree(int fd, drm_handle_t handle)
1657{ 1786{
1658 drm_agp_buffer_t b; 1787 drm_agp_buffer_t b;
1659 1788
1660 b.size = 0; 1789 memclear(b);
1661 b.handle = handle; 1790 b.handle = handle;
1662 if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b)) 1791 if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
1663 return -errno; 1792 return -errno;
@@ -1682,6 +1811,7 @@ int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
1682{ 1811{
1683 drm_agp_binding_t b; 1812 drm_agp_binding_t b;
1684 1813
1814 memclear(b);
1685 b.handle = handle; 1815 b.handle = handle;
1686 b.offset = offset; 1816 b.offset = offset;
1687 if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b)) 1817 if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
@@ -1706,8 +1836,8 @@ int drmAgpUnbind(int fd, drm_handle_t handle)
1706{ 1836{
1707 drm_agp_binding_t b; 1837 drm_agp_binding_t b;
1708 1838
1839 memclear(b);
1709 b.handle = handle; 1840 b.handle = handle;
1710 b.offset = 0;
1711 if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) 1841 if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
1712 return -errno; 1842 return -errno;
1713 return 0; 1843 return 0;
@@ -1729,6 +1859,8 @@ int drmAgpVersionMajor(int fd)
1729{ 1859{
1730 drm_agp_info_t i; 1860 drm_agp_info_t i;
1731 1861
1862 memclear(i);
1863
1732 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1864 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1733 return -errno; 1865 return -errno;
1734 return i.agp_version_major; 1866 return i.agp_version_major;
@@ -1750,6 +1882,8 @@ int drmAgpVersionMinor(int fd)
1750{ 1882{
1751 drm_agp_info_t i; 1883 drm_agp_info_t i;
1752 1884
1885 memclear(i);
1886
1753 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1887 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1754 return -errno; 1888 return -errno;
1755 return i.agp_version_minor; 1889 return i.agp_version_minor;
@@ -1771,6 +1905,8 @@ unsigned long drmAgpGetMode(int fd)
1771{ 1905{
1772 drm_agp_info_t i; 1906 drm_agp_info_t i;
1773 1907
1908 memclear(i);
1909
1774 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1910 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1775 return 0; 1911 return 0;
1776 return i.mode; 1912 return i.mode;
@@ -1792,6 +1928,8 @@ unsigned long drmAgpBase(int fd)
1792{ 1928{
1793 drm_agp_info_t i; 1929 drm_agp_info_t i;
1794 1930
1931 memclear(i);
1932
1795 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1933 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1796 return 0; 1934 return 0;
1797 return i.aperture_base; 1935 return i.aperture_base;
@@ -1813,6 +1951,8 @@ unsigned long drmAgpSize(int fd)
1813{ 1951{
1814 drm_agp_info_t i; 1952 drm_agp_info_t i;
1815 1953
1954 memclear(i);
1955
1816 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1956 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1817 return 0; 1957 return 0;
1818 return i.aperture_size; 1958 return i.aperture_size;
@@ -1834,6 +1974,8 @@ unsigned long drmAgpMemoryUsed(int fd)
1834{ 1974{
1835 drm_agp_info_t i; 1975 drm_agp_info_t i;
1836 1976
1977 memclear(i);
1978
1837 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1979 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1838 return 0; 1980 return 0;
1839 return i.memory_used; 1981 return i.memory_used;
@@ -1855,6 +1997,8 @@ unsigned long drmAgpMemoryAvail(int fd)
1855{ 1997{
1856 drm_agp_info_t i; 1998 drm_agp_info_t i;
1857 1999
2000 memclear(i);
2001
1858 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 2002 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1859 return 0; 2003 return 0;
1860 return i.memory_allowed; 2004 return i.memory_allowed;
@@ -1876,6 +2020,8 @@ unsigned int drmAgpVendorId(int fd)
1876{ 2020{
1877 drm_agp_info_t i; 2021 drm_agp_info_t i;
1878 2022
2023 memclear(i);
2024
1879 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 2025 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1880 return 0; 2026 return 0;
1881 return i.id_vendor; 2027 return i.id_vendor;
@@ -1897,6 +2043,8 @@ unsigned int drmAgpDeviceId(int fd)
1897{ 2043{
1898 drm_agp_info_t i; 2044 drm_agp_info_t i;
1899 2045
2046 memclear(i);
2047
1900 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 2048 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1901 return 0; 2049 return 0;
1902 return i.id_device; 2050 return i.id_device;
@@ -1906,9 +2054,10 @@ int drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
1906{ 2054{
1907 drm_scatter_gather_t sg; 2055 drm_scatter_gather_t sg;
1908 2056
2057 memclear(sg);
2058
1909 *handle = 0; 2059 *handle = 0;
1910 sg.size = size; 2060 sg.size = size;
1911 sg.handle = 0;
1912 if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) 2061 if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
1913 return -errno; 2062 return -errno;
1914 *handle = sg.handle; 2063 *handle = sg.handle;
@@ -1919,7 +2068,7 @@ int drmScatterGatherFree(int fd, drm_handle_t handle)
1919{ 2068{
1920 drm_scatter_gather_t sg; 2069 drm_scatter_gather_t sg;
1921 2070
1922 sg.size = 0; 2071 memclear(sg);
1923 sg.handle = handle; 2072 sg.handle = handle;
1924 if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg)) 2073 if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
1925 return -errno; 2074 return -errno;
@@ -2010,6 +2159,7 @@ int drmCtlInstHandler(int fd, int irq)
2010{ 2159{
2011 drm_control_t ctl; 2160 drm_control_t ctl;
2012 2161
2162 memclear(ctl);
2013 ctl.func = DRM_INST_HANDLER; 2163 ctl.func = DRM_INST_HANDLER;
2014 ctl.irq = irq; 2164 ctl.irq = irq;
2015 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 2165 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
@@ -2033,6 +2183,7 @@ int drmCtlUninstHandler(int fd)
2033{ 2183{
2034 drm_control_t ctl; 2184 drm_control_t ctl;
2035 2185
2186 memclear(ctl);
2036 ctl.func = DRM_UNINST_HANDLER; 2187 ctl.func = DRM_UNINST_HANDLER;
2037 ctl.irq = 0; 2188 ctl.irq = 0;
2038 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 2189 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
@@ -2044,8 +2195,8 @@ int drmFinish(int fd, int context, drmLockFlags flags)
2044{ 2195{
2045 drm_lock_t lock; 2196 drm_lock_t lock;
2046 2197
2198 memclear(lock);
2047 lock.context = context; 2199 lock.context = context;
2048 lock.flags = 0;
2049 if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; 2200 if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
2050 if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; 2201 if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
2051 if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; 2202 if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
@@ -2075,6 +2226,7 @@ int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
2075{ 2226{
2076 drm_irq_busid_t p; 2227 drm_irq_busid_t p;
2077 2228
2229 memclear(p);
2078 p.busnum = busnum; 2230 p.busnum = busnum;
2079 p.devnum = devnum; 2231 p.devnum = devnum;
2080 p.funcnum = funcnum; 2232 p.funcnum = funcnum;
@@ -2117,6 +2269,7 @@ int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
2117{ 2269{
2118 drm_ctx_priv_map_t map; 2270 drm_ctx_priv_map_t map;
2119 2271
2272 memclear(map);
2120 map.ctx_id = ctx_id; 2273 map.ctx_id = ctx_id;
2121 map.handle = (void *)(uintptr_t)handle; 2274 map.handle = (void *)(uintptr_t)handle;
2122 2275
@@ -2130,6 +2283,7 @@ int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
2130{ 2283{
2131 drm_ctx_priv_map_t map; 2284 drm_ctx_priv_map_t map;
2132 2285
2286 memclear(map);
2133 map.ctx_id = ctx_id; 2287 map.ctx_id = ctx_id;
2134 2288
2135 if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) 2289 if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
@@ -2146,6 +2300,7 @@ int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
2146{ 2300{
2147 drm_map_t map; 2301 drm_map_t map;
2148 2302
2303 memclear(map);
2149 map.offset = idx; 2304 map.offset = idx;
2150 if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map)) 2305 if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
2151 return -errno; 2306 return -errno;
@@ -2163,6 +2318,7 @@ int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
2163{ 2318{
2164 drm_client_t client; 2319 drm_client_t client;
2165 2320
2321 memclear(client);
2166 client.idx = idx; 2322 client.idx = idx;
2167 if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client)) 2323 if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
2168 return -errno; 2324 return -errno;
@@ -2177,8 +2333,9 @@ int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
2177int drmGetStats(int fd, drmStatsT *stats) 2333int drmGetStats(int fd, drmStatsT *stats)
2178{ 2334{
2179 drm_stats_t s; 2335 drm_stats_t s;
2180 int i; 2336 unsigned i;
2181 2337
2338 memclear(s);
2182 if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s)) 2339 if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
2183 return -errno; 2340 return -errno;
2184 2341
@@ -2316,6 +2473,7 @@ int drmSetInterfaceVersion(int fd, drmSetVersion *version)
2316 int retcode = 0; 2473 int retcode = 0;
2317 drm_set_version_t sv; 2474 drm_set_version_t sv;
2318 2475
2476 memclear(sv);
2319 sv.drm_di_major = version->drm_di_major; 2477 sv.drm_di_major = version->drm_di_major;
2320 sv.drm_di_minor = version->drm_di_minor; 2478 sv.drm_di_minor = version->drm_di_minor;
2321 sv.drm_dd_major = version->drm_dd_major; 2479 sv.drm_dd_major = version->drm_dd_major;
@@ -2347,12 +2505,11 @@ int drmSetInterfaceVersion(int fd, drmSetVersion *version)
2347 */ 2505 */
2348int drmCommandNone(int fd, unsigned long drmCommandIndex) 2506int drmCommandNone(int fd, unsigned long drmCommandIndex)
2349{ 2507{
2350 void *data = NULL; /* dummy */
2351 unsigned long request; 2508 unsigned long request;
2352 2509
2353 request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex); 2510 request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
2354 2511
2355 if (drmIoctl(fd, request, data)) { 2512 if (drmIoctl(fd, request, NULL)) {
2356 return -errno; 2513 return -errno;
2357 } 2514 }
2358 return 0; 2515 return 0;
@@ -2449,6 +2606,7 @@ static struct {
2449 char *BusID; 2606 char *BusID;
2450 int fd; 2607 int fd;
2451 int refcount; 2608 int refcount;
2609 int type;
2452} connection[DRM_MAX_FDS]; 2610} connection[DRM_MAX_FDS];
2453 2611
2454static int nr_fds = 0; 2612static int nr_fds = 0;
@@ -2457,23 +2615,30 @@ int drmOpenOnce(void *unused,
2457 const char *BusID, 2615 const char *BusID,
2458 int *newlyopened) 2616 int *newlyopened)
2459{ 2617{
2618 return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY);
2619}
2620
2621int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type)
2622{
2460 int i; 2623 int i;
2461 int fd; 2624 int fd;
2462 2625
2463 for (i = 0; i < nr_fds; i++) 2626 for (i = 0; i < nr_fds; i++)
2464 if (strcmp(BusID, connection[i].BusID) == 0) { 2627 if ((strcmp(BusID, connection[i].BusID) == 0) &&
2628 (connection[i].type == type)) {
2465 connection[i].refcount++; 2629 connection[i].refcount++;
2466 *newlyopened = 0; 2630 *newlyopened = 0;
2467 return connection[i].fd; 2631 return connection[i].fd;
2468 } 2632 }
2469 2633
2470 fd = drmOpen(unused, BusID); 2634 fd = drmOpenWithType(NULL, BusID, type);
2471 if (fd <= 0 || nr_fds == DRM_MAX_FDS) 2635 if (fd < 0 || nr_fds == DRM_MAX_FDS)
2472 return fd; 2636 return fd;
2473 2637
2474 connection[nr_fds].BusID = strdup(BusID); 2638 connection[nr_fds].BusID = strdup(BusID);
2475 connection[nr_fds].fd = fd; 2639 connection[nr_fds].fd = fd;
2476 connection[nr_fds].refcount = 1; 2640 connection[nr_fds].refcount = 1;
2641 connection[nr_fds].type = type;
2477 *newlyopened = 1; 2642 *newlyopened = 1;
2478 2643
2479 if (0) 2644 if (0)
@@ -2507,12 +2672,12 @@ void drmCloseOnce(int fd)
2507 2672
2508int drmSetMaster(int fd) 2673int drmSetMaster(int fd)
2509{ 2674{
2510 return ioctl(fd, DRM_IOCTL_SET_MASTER, 0); 2675 return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL);
2511} 2676}
2512 2677
2513int drmDropMaster(int fd) 2678int drmDropMaster(int fd)
2514{ 2679{
2515 return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); 2680 return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL);
2516} 2681}
2517 2682
2518char *drmGetDeviceNameFromFd(int fd) 2683char *drmGetDeviceNameFromFd(int fd)
@@ -2541,11 +2706,35 @@ char *drmGetDeviceNameFromFd(int fd)
2541 return strdup(name); 2706 return strdup(name);
2542} 2707}
2543 2708
2709int drmGetNodeTypeFromFd(int fd)
2710{
2711 struct stat sbuf;
2712 int maj, min, type;
2713
2714 if (fstat(fd, &sbuf))
2715 return -1;
2716
2717 maj = major(sbuf.st_rdev);
2718 min = minor(sbuf.st_rdev);
2719
2720 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) {
2721 errno = EINVAL;
2722 return -1;
2723 }
2724
2725 type = drmGetMinorType(min);
2726 if (type == -1)
2727 errno = ENODEV;
2728 return type;
2729}
2730
2544int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd) 2731int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
2545{ 2732{
2546 struct drm_prime_handle args; 2733 struct drm_prime_handle args;
2547 int ret; 2734 int ret;
2548 2735
2736 memclear(args);
2737 args.fd = -1;
2549 args.handle = handle; 2738 args.handle = handle;
2550 args.flags = flags; 2739 args.flags = flags;
2551 ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); 2740 ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
@@ -2561,8 +2750,8 @@ int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
2561 struct drm_prime_handle args; 2750 struct drm_prime_handle args;
2562 int ret; 2751 int ret;
2563 2752
2753 memclear(args);
2564 args.fd = prime_fd; 2754 args.fd = prime_fd;
2565 args.flags = 0;
2566 ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args); 2755 ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
2567 if (ret) 2756 if (ret)
2568 return ret; 2757 return ret;
@@ -2571,3 +2760,530 @@ int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
2571 return 0; 2760 return 0;
2572} 2761}
2573 2762
2763static char *drmGetMinorNameForFD(int fd, int type)
2764{
2765#ifdef __linux__
2766 DIR *sysdir;
2767 struct dirent *pent, *ent;
2768 struct stat sbuf;
2769 const char *name = drmGetMinorName(type);
2770 int len;
2771 char dev_name[64], buf[64];
2772 long name_max;
2773 int maj, min;
2774
2775 if (!name)
2776 return NULL;
2777
2778 len = strlen(name);
2779
2780 if (fstat(fd, &sbuf))
2781 return NULL;
2782
2783 maj = major(sbuf.st_rdev);
2784 min = minor(sbuf.st_rdev);
2785
2786 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
2787 return NULL;
2788
2789 snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min);
2790
2791 sysdir = opendir(buf);
2792 if (!sysdir)
2793 return NULL;
2794
2795 name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX);
2796 if (name_max == -1)
2797 goto out_close_dir;
2798
2799 pent = malloc(offsetof(struct dirent, d_name) + name_max + 1);
2800 if (pent == NULL)
2801 goto out_close_dir;
2802
2803 while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) {
2804 if (strncmp(ent->d_name, name, len) == 0) {
2805 snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
2806 ent->d_name);
2807
2808 free(pent);
2809 closedir(sysdir);
2810
2811 return strdup(dev_name);
2812 }
2813 }
2814
2815 free(pent);
2816
2817out_close_dir:
2818 closedir(sysdir);
2819#else
2820#warning "Missing implementation of drmGetMinorNameForFD"
2821#endif
2822 return NULL;
2823}
2824
2825char *drmGetPrimaryDeviceNameFromFd(int fd)
2826{
2827 return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY);
2828}
2829
2830char *drmGetRenderDeviceNameFromFd(int fd)
2831{
2832 return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
2833}
2834
2835static int drmParseSubsystemType(int maj, int min)
2836{
2837#ifdef __linux__
2838 char path[PATH_MAX + 1];
2839 char link[PATH_MAX + 1] = "";
2840 char *name;
2841
2842 snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/subsystem",
2843 maj, min);
2844
2845 if (readlink(path, link, PATH_MAX) < 0)
2846 return -errno;
2847
2848 name = strrchr(link, '/');
2849 if (!name)
2850 return -EINVAL;
2851
2852 if (strncmp(name, "/pci", 4) == 0)
2853 return DRM_BUS_PCI;
2854
2855 return -EINVAL;
2856#else
2857#warning "Missing implementation of drmParseSubsystemType"
2858 return -EINVAL;
2859#endif
2860}
2861
2862static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
2863{
2864#ifdef __linux__
2865 char path[PATH_MAX + 1];
2866 char data[128];
2867 char *str;
2868 int domain, bus, dev, func;
2869 int fd, ret;
2870
2871 snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/uevent", maj, min);
2872 fd = open(path, O_RDONLY);
2873 if (fd < 0)
2874 return -errno;
2875
2876 ret = read(fd, data, sizeof(data));
2877 close(fd);
2878 if (ret < 0)
2879 return -errno;
2880
2881#define TAG "PCI_SLOT_NAME="
2882 str = strstr(data, TAG);
2883 if (str == NULL)
2884 return -EINVAL;
2885
2886 if (sscanf(str, TAG "%04x:%02x:%02x.%1u",
2887 &domain, &bus, &dev, &func) != 4)
2888 return -EINVAL;
2889#undef TAG
2890
2891 info->domain = domain;
2892 info->bus = bus;
2893 info->dev = dev;
2894 info->func = func;
2895
2896 return 0;
2897#else
2898#warning "Missing implementation of drmParsePciBusInfo"
2899 return -EINVAL;
2900#endif
2901}
2902
2903static int drmCompareBusInfo(drmDevicePtr a, drmDevicePtr b)
2904{
2905 if (a == NULL || b == NULL)
2906 return -1;
2907
2908 if (a->bustype != b->bustype)
2909 return -1;
2910
2911 switch (a->bustype) {
2912 case DRM_BUS_PCI:
2913 return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo));
2914 default:
2915 break;
2916 }
2917
2918 return -1;
2919}
2920
2921static int drmGetNodeType(const char *name)
2922{
2923 if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
2924 sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
2925 return DRM_NODE_PRIMARY;
2926
2927 if (strncmp(name, DRM_CONTROL_MINOR_NAME,
2928 sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0)
2929 return DRM_NODE_CONTROL;
2930
2931 if (strncmp(name, DRM_RENDER_MINOR_NAME,
2932 sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
2933 return DRM_NODE_RENDER;
2934
2935 return -EINVAL;
2936}
2937
2938static int drmGetMaxNodeName(void)
2939{
2940 return sizeof(DRM_DIR_NAME) +
2941 MAX3(sizeof(DRM_PRIMARY_MINOR_NAME),
2942 sizeof(DRM_CONTROL_MINOR_NAME),
2943 sizeof(DRM_RENDER_MINOR_NAME)) +
2944 3 /* lenght of the node number */;
2945}
2946
2947static int drmParsePciDeviceInfo(const char *d_name,
2948 drmPciDeviceInfoPtr device)
2949{
2950#ifdef __linux__
2951 char path[PATH_MAX + 1];
2952 unsigned char config[64];
2953 int fd, ret;
2954
2955 snprintf(path, PATH_MAX, "/sys/class/drm/%s/device/config", d_name);
2956 fd = open(path, O_RDONLY);
2957 if (fd < 0)
2958 return -errno;
2959
2960 ret = read(fd, config, sizeof(config));
2961 close(fd);
2962 if (ret < 0)
2963 return -errno;
2964
2965 device->vendor_id = config[0] | (config[1] << 8);
2966 device->device_id = config[2] | (config[3] << 8);
2967 device->revision_id = config[8];
2968 device->subvendor_id = config[44] | (config[45] << 8);
2969 device->subdevice_id = config[46] | (config[47] << 8);
2970
2971 return 0;
2972#else
2973#warning "Missing implementation of drmParsePciDeviceInfo"
2974 return -EINVAL;
2975#endif
2976}
2977
2978void drmFreeDevice(drmDevicePtr *device)
2979{
2980 if (device == NULL)
2981 return;
2982
2983 free(*device);
2984 *device = NULL;
2985}
2986
2987void drmFreeDevices(drmDevicePtr devices[], int count)
2988{
2989 int i;
2990
2991 if (devices == NULL)
2992 return;
2993
2994 for (i = 0; i < count && devices[i] != NULL; i++)
2995 drmFreeDevice(&devices[i]);
2996}
2997
2998static int drmProcessPciDevice(drmDevicePtr *device, const char *d_name,
2999 const char *node, int node_type,
3000 int maj, int min, bool fetch_deviceinfo)
3001{
3002 const int max_node_str = drmGetMaxNodeName();
3003 int ret, i;
3004 char *addr;
3005
3006 *device = calloc(1, sizeof(drmDevice) +
3007 (DRM_NODE_MAX * (sizeof(void *) + max_node_str)) +
3008 sizeof(drmPciBusInfo) +
3009 sizeof(drmPciDeviceInfo));
3010 if (!*device)
3011 return -ENOMEM;
3012
3013 addr = (char*)*device;
3014
3015 (*device)->bustype = DRM_BUS_PCI;
3016 (*device)->available_nodes = 1 << node_type;
3017
3018 addr += sizeof(drmDevice);
3019 (*device)->nodes = (char**)addr;
3020
3021 addr += DRM_NODE_MAX * sizeof(void *);
3022 for (i = 0; i < DRM_NODE_MAX; i++) {
3023 (*device)->nodes[i] = addr;
3024 addr += max_node_str;
3025 }
3026 memcpy((*device)->nodes[node_type], node, max_node_str);
3027
3028 (*device)->businfo.pci = (drmPciBusInfoPtr)addr;
3029
3030 ret = drmParsePciBusInfo(maj, min, (*device)->businfo.pci);
3031 if (ret)
3032 goto free_device;
3033
3034 // Fetch the device info if the user has requested it
3035 if (fetch_deviceinfo) {
3036 addr += sizeof(drmPciBusInfo);
3037 (*device)->deviceinfo.pci = (drmPciDeviceInfoPtr)addr;
3038
3039 ret = drmParsePciDeviceInfo(d_name, (*device)->deviceinfo.pci);
3040 if (ret)
3041 goto free_device;
3042 }
3043 return 0;
3044
3045free_device:
3046 free(*device);
3047 *device = NULL;
3048 return ret;
3049}
3050
3051static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
3052{
3053 int node_type, i, j;
3054
3055 for (i = 0; i < count; i++) {
3056 for (j = i + 1; j < count; j++) {
3057 if (drmCompareBusInfo(local_devices[i], local_devices[j]) == 0) {
3058 local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
3059 node_type = log2(local_devices[j]->available_nodes);
3060 memcpy(local_devices[i]->nodes[node_type],
3061 local_devices[j]->nodes[node_type], drmGetMaxNodeName());
3062 drmFreeDevice(&local_devices[j]);
3063 }
3064 }
3065 }
3066}
3067
3068/**
3069 * Get information about the opened drm device
3070 *
3071 * \param fd file descriptor of the drm device
3072 * \param device the address of a drmDevicePtr where the information
3073 * will be allocated in stored
3074 *
3075 * \return zero on success, negative error code otherwise.
3076 */
3077int drmGetDevice(int fd, drmDevicePtr *device)
3078{
3079 drmDevicePtr *local_devices;
3080 drmDevicePtr d;
3081 DIR *sysdir;
3082 struct dirent *dent;
3083 struct stat sbuf;
3084 char node[PATH_MAX + 1];
3085 int node_type, subsystem_type;
3086 int maj, min;
3087 int ret, i, node_count;
3088 int max_count = 16;
3089
3090 if (fd == -1 || device == NULL)
3091 return -EINVAL;
3092
3093 if (fstat(fd, &sbuf))
3094 return -errno;
3095
3096 maj = major(sbuf.st_rdev);
3097 min = minor(sbuf.st_rdev);
3098
3099 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
3100 return -EINVAL;
3101
3102 subsystem_type = drmParseSubsystemType(maj, min);
3103
3104 local_devices = calloc(max_count, sizeof(drmDevicePtr));
3105 if (local_devices == NULL)
3106 return -ENOMEM;
3107
3108 sysdir = opendir(DRM_DIR_NAME);
3109 if (!sysdir) {
3110 ret = -errno;
3111 goto free_locals;
3112 }
3113
3114 i = 0;
3115 while ((dent = readdir(sysdir))) {
3116 node_type = drmGetNodeType(dent->d_name);
3117 if (node_type < 0)
3118 continue;
3119
3120 snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
3121 if (stat(node, &sbuf))
3122 continue;
3123
3124 maj = major(sbuf.st_rdev);
3125 min = minor(sbuf.st_rdev);
3126
3127 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
3128 continue;
3129
3130 if (drmParseSubsystemType(maj, min) != subsystem_type)
3131 continue;
3132
3133 switch (subsystem_type) {
3134 case DRM_BUS_PCI:
3135 ret = drmProcessPciDevice(&d, dent->d_name, node, node_type,
3136 maj, min, true);
3137 if (ret)
3138 goto free_devices;
3139
3140 break;
3141 default:
3142 fprintf(stderr, "The subsystem type is not supported yet\n");
3143 continue;
3144 }
3145
3146 if (i >= max_count) {
3147 drmDevicePtr *temp;
3148
3149 max_count += 16;
3150 temp = realloc(local_devices, max_count * sizeof(drmDevicePtr));
3151 if (!temp)
3152 goto free_devices;
3153 local_devices = temp;
3154 }
3155
3156 local_devices[i] = d;
3157 i++;
3158 }
3159 node_count = i;
3160
3161 /* Fold nodes into a single device if they share the same bus info */
3162 drmFoldDuplicatedDevices(local_devices, node_count);
3163
3164 *device = local_devices[0];
3165 for (i = 1; i < node_count && local_devices[i]; i++)
3166 drmFreeDevice(&local_devices[i]);
3167
3168 closedir(sysdir);
3169 free(local_devices);
3170 return 0;
3171
3172free_devices:
3173 drmFreeDevices(local_devices, i);
3174 closedir(sysdir);
3175
3176free_locals:
3177 free(local_devices);
3178 return ret;
3179}
3180
3181/**
3182 * Get drm devices on the system
3183 *
3184 * \param devices the array of devices with drmDevicePtr elements
3185 * can be NULL to get the device number first
3186 * \param max_devices the maximum number of devices for the array
3187 *
3188 * \return on error - negative error code,
3189 * if devices is NULL - total number of devices available on the system,
3190 * alternatively the number of devices stored in devices[], which is
3191 * capped by the max_devices.
3192 */
3193int drmGetDevices(drmDevicePtr devices[], int max_devices)
3194{
3195 drmDevicePtr *local_devices;
3196 drmDevicePtr device;
3197 DIR *sysdir;
3198 struct dirent *dent;
3199 struct stat sbuf;
3200 char node[PATH_MAX + 1];
3201 int node_type, subsystem_type;
3202 int maj, min;
3203 int ret, i, node_count, device_count;
3204 int max_count = 16;
3205
3206 local_devices = calloc(max_count, sizeof(drmDevicePtr));
3207 if (local_devices == NULL)
3208 return -ENOMEM;
3209
3210 sysdir = opendir(DRM_DIR_NAME);
3211 if (!sysdir) {
3212 ret = -errno;
3213 goto free_locals;
3214 }
3215
3216 i = 0;
3217 while ((dent = readdir(sysdir))) {
3218 node_type = drmGetNodeType(dent->d_name);
3219 if (node_type < 0)
3220 continue;
3221
3222 snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name);
3223 if (stat(node, &sbuf))
3224 continue;
3225
3226 maj = major(sbuf.st_rdev);
3227 min = minor(sbuf.st_rdev);
3228
3229 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
3230 continue;
3231
3232 subsystem_type = drmParseSubsystemType(maj, min);
3233
3234 if (subsystem_type < 0)
3235 continue;
3236
3237 switch (subsystem_type) {
3238 case DRM_BUS_PCI:
3239 ret = drmProcessPciDevice(&device, dent->d_name, node, node_type,
3240 maj, min, devices != NULL);
3241 if (ret)
3242 goto free_devices;
3243
3244 break;
3245 default:
3246 fprintf(stderr, "The subsystem type is not supported yet\n");
3247 continue;
3248 }
3249
3250 if (i >= max_count) {
3251 drmDevicePtr *temp;
3252
3253 max_count += 16;
3254 temp = realloc(local_devices, max_count * sizeof(drmDevicePtr));
3255 if (!temp)
3256 goto free_devices;
3257 local_devices = temp;
3258 }
3259
3260 local_devices[i] = device;
3261 i++;
3262 }
3263 node_count = i;
3264
3265 /* Fold nodes into a single device if they share the same bus info */
3266 drmFoldDuplicatedDevices(local_devices, node_count);
3267
3268 device_count = 0;
3269 for (i = 0; i < node_count && local_devices[i]; i++) {
3270 if ((devices != NULL) && (device_count < max_devices))
3271 devices[device_count] = local_devices[i];
3272 else
3273 drmFreeDevice(&local_devices[i]);
3274
3275 device_count++;
3276 }
3277
3278 closedir(sysdir);
3279 free(local_devices);
3280 return device_count;
3281
3282free_devices:
3283 drmFreeDevices(local_devices, i);
3284 closedir(sysdir);
3285
3286free_locals:
3287 free(local_devices);
3288 return ret;
3289}
diff --git a/xf86drm.h b/xf86drm.h
index c024cc44..481d882a 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -39,7 +39,7 @@
39#include <stdint.h> 39#include <stdint.h>
40#include <drm.h> 40#include <drm.h>
41 41
42#if defined(__cplusplus) || defined(c_plusplus) 42#if defined(__cplusplus)
43extern "C" { 43extern "C" {
44#endif 44#endif
45 45
@@ -76,10 +76,18 @@ extern "C" {
76 (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 76 (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
77#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) 77#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
78 78
79#ifdef __OpenBSD__
80#define DRM_DIR_NAME "/dev"
81#define DRM_DEV_NAME "%s/drm%d"
82#define DRM_CONTROL_DEV_NAME "%s/drmC%d"
83#define DRM_RENDER_DEV_NAME "%s/drmR%d"
84#else
79#define DRM_DIR_NAME "/dev/dri" 85#define DRM_DIR_NAME "/dev/dri"
80#define DRM_DEV_NAME "%s/card%d" 86#define DRM_DEV_NAME "%s/card%d"
81#define DRM_CONTROL_DEV_NAME "%s/controlD%d" 87#define DRM_CONTROL_DEV_NAME "%s/controlD%d"
88#define DRM_RENDER_DEV_NAME "%s/renderD%d"
82#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */ 89#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
90#endif
83 91
84#define DRM_ERR_NO_DEVICE (-1001) 92#define DRM_ERR_NO_DEVICE (-1001)
85#define DRM_ERR_NO_ACCESS (-1002) 93#define DRM_ERR_NO_ACCESS (-1002)
@@ -551,7 +559,17 @@ do { register unsigned int __old __asm("o0"); \
551/* General user-level programmer's API: unprivileged */ 559/* General user-level programmer's API: unprivileged */
552extern int drmAvailable(void); 560extern int drmAvailable(void);
553extern int drmOpen(const char *name, const char *busid); 561extern int drmOpen(const char *name, const char *busid);
554extern int drmOpenControl(int minor); 562
563#define DRM_NODE_PRIMARY 0
564#define DRM_NODE_CONTROL 1
565#define DRM_NODE_RENDER 2
566#define DRM_NODE_MAX 3
567
568extern int drmOpenWithType(const char *name, const char *busid,
569 int type);
570
571extern int drmOpenControl(int minor);
572extern int drmOpenRender(int minor);
555extern int drmClose(int fd); 573extern int drmClose(int fd);
556extern drmVersionPtr drmGetVersion(int fd); 574extern drmVersionPtr drmGetVersion(int fd);
557extern drmVersionPtr drmGetLibVersion(int fd); 575extern drmVersionPtr drmGetLibVersion(int fd);
@@ -703,6 +721,7 @@ extern int drmSLLookupNeighbors(void *l, unsigned long key,
703 unsigned long *next_key, void **next_value); 721 unsigned long *next_key, void **next_value);
704 722
705extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened); 723extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened);
724extern int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type);
706extern void drmCloseOnce(int fd); 725extern void drmCloseOnce(int fd);
707extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2); 726extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2);
708 727
@@ -734,11 +753,50 @@ typedef struct _drmEventContext {
734extern int drmHandleEvent(int fd, drmEventContextPtr evctx); 753extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
735 754
736extern char *drmGetDeviceNameFromFd(int fd); 755extern char *drmGetDeviceNameFromFd(int fd);
756extern int drmGetNodeTypeFromFd(int fd);
737 757
738extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd); 758extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);
739extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle); 759extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle);
740 760
741#if defined(__cplusplus) || defined(c_plusplus) 761extern char *drmGetPrimaryDeviceNameFromFd(int fd);
762extern char *drmGetRenderDeviceNameFromFd(int fd);
763
764#define DRM_BUS_PCI 0
765
766typedef struct _drmPciBusInfo {
767 uint16_t domain;
768 uint8_t bus;
769 uint8_t dev;
770 uint8_t func;
771} drmPciBusInfo, *drmPciBusInfoPtr;
772
773typedef struct _drmPciDeviceInfo {
774 uint16_t vendor_id;
775 uint16_t device_id;
776 uint16_t subvendor_id;
777 uint16_t subdevice_id;
778 uint8_t revision_id;
779} drmPciDeviceInfo, *drmPciDeviceInfoPtr;
780
781typedef struct _drmDevice {
782 char **nodes; /* DRM_NODE_MAX sized array */
783 int available_nodes; /* DRM_NODE_* bitmask */
784 int bustype;
785 union {
786 drmPciBusInfoPtr pci;
787 } businfo;
788 union {
789 drmPciDeviceInfoPtr pci;
790 } deviceinfo;
791} drmDevice, *drmDevicePtr;
792
793extern int drmGetDevice(int fd, drmDevicePtr *device);
794extern void drmFreeDevice(drmDevicePtr *device);
795
796extern int drmGetDevices(drmDevicePtr devices[], int max_devices);
797extern void drmFreeDevices(drmDevicePtr devices[], int count);
798
799#if defined(__cplusplus)
742} 800}
743#endif 801#endif
744 802
diff --git a/xf86drmHash.c b/xf86drmHash.c
index 82cbc2a5..f287e61f 100644
--- a/xf86drmHash.c
+++ b/xf86drmHash.c
@@ -71,60 +71,10 @@
71#include <stdio.h> 71#include <stdio.h>
72#include <stdlib.h> 72#include <stdlib.h>
73 73
74#define HASH_MAIN 0 74#include "xf86drm.h"
75 75#include "xf86drmHash.h"
76#if !HASH_MAIN
77# include "xf86drm.h"
78#endif
79 76
80#define HASH_MAGIC 0xdeadbeef 77#define HASH_MAGIC 0xdeadbeef
81#define HASH_DEBUG 0
82#define HASH_SIZE 512 /* Good for about 100 entries */
83 /* If you change this value, you probably
84 have to change the HashHash hashing
85 function! */
86
87#if HASH_MAIN
88#define HASH_ALLOC malloc
89#define HASH_FREE free
90#define HASH_RANDOM_DECL
91#define HASH_RANDOM_INIT(seed) srandom(seed)
92#define HASH_RANDOM random()
93#define HASH_RANDOM_DESTROY
94#else
95#define HASH_ALLOC drmMalloc
96#define HASH_FREE drmFree
97#define HASH_RANDOM_DECL void *state
98#define HASH_RANDOM_INIT(seed) state = drmRandomCreate(seed)
99#define HASH_RANDOM drmRandom(state)
100#define HASH_RANDOM_DESTROY drmRandomDestroy(state)
101
102#endif
103
104typedef struct HashBucket {
105 unsigned long key;
106 void *value;
107 struct HashBucket *next;
108} HashBucket, *HashBucketPtr;
109
110typedef struct HashTable {
111 unsigned long magic;
112 unsigned long entries;
113 unsigned long hits; /* At top of linked list */
114 unsigned long partials; /* Not at top of linked list */
115 unsigned long misses; /* Not in table */
116 HashBucketPtr buckets[HASH_SIZE];
117 int p0;
118 HashBucketPtr p1;
119} HashTable, *HashTablePtr;
120
121#if HASH_MAIN
122extern void *drmHashCreate(void);
123extern int drmHashDestroy(void *t);
124extern int drmHashLookup(void *t, unsigned long key, unsigned long *value);
125extern int drmHashInsert(void *t, unsigned long key, unsigned long value);
126extern int drmHashDelete(void *t, unsigned long key);
127#endif
128 78
129static unsigned long HashHash(unsigned long key) 79static unsigned long HashHash(unsigned long key)
130{ 80{
@@ -135,10 +85,10 @@ static unsigned long HashHash(unsigned long key)
135 int i; 85 int i;
136 86
137 if (!init) { 87 if (!init) {
138 HASH_RANDOM_DECL; 88 void *state;
139 HASH_RANDOM_INIT(37); 89 state = drmRandomCreate(37);
140 for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM; 90 for (i = 0; i < 256; i++) scatter[i] = drmRandom(state);
141 HASH_RANDOM_DESTROY; 91 drmRandomDestroy(state);
142 ++init; 92 ++init;
143 } 93 }
144 94
@@ -148,8 +98,8 @@ static unsigned long HashHash(unsigned long key)
148 } 98 }
149 99
150 hash %= HASH_SIZE; 100 hash %= HASH_SIZE;
151#if HASH_DEBUG 101#if DEBUG
152 printf( "Hash(%d) = %d\n", key, hash); 102 printf( "Hash(%lu) = %lu\n", key, hash);
153#endif 103#endif
154 return hash; 104 return hash;
155} 105}
@@ -159,7 +109,7 @@ void *drmHashCreate(void)
159 HashTablePtr table; 109 HashTablePtr table;
160 int i; 110 int i;
161 111
162 table = HASH_ALLOC(sizeof(*table)); 112 table = drmMalloc(sizeof(*table));
163 if (!table) return NULL; 113 if (!table) return NULL;
164 table->magic = HASH_MAGIC; 114 table->magic = HASH_MAGIC;
165 table->entries = 0; 115 table->entries = 0;
@@ -183,11 +133,11 @@ int drmHashDestroy(void *t)
183 for (i = 0; i < HASH_SIZE; i++) { 133 for (i = 0; i < HASH_SIZE; i++) {
184 for (bucket = table->buckets[i]; bucket;) { 134 for (bucket = table->buckets[i]; bucket;) {
185 next = bucket->next; 135 next = bucket->next;
186 HASH_FREE(bucket); 136 drmFree(bucket);
187 bucket = next; 137 bucket = next;
188 } 138 }
189 } 139 }
190 HASH_FREE(table); 140 drmFree(table);
191 return 0; 141 return 0;
192} 142}
193 143
@@ -245,14 +195,14 @@ int drmHashInsert(void *t, unsigned long key, void *value)
245 195
246 if (HashFind(table, key, &hash)) return 1; /* Already in table */ 196 if (HashFind(table, key, &hash)) return 1; /* Already in table */
247 197
248 bucket = HASH_ALLOC(sizeof(*bucket)); 198 bucket = drmMalloc(sizeof(*bucket));
249 if (!bucket) return -1; /* Error */ 199 if (!bucket) return -1; /* Error */
250 bucket->key = key; 200 bucket->key = key;
251 bucket->value = value; 201 bucket->value = value;
252 bucket->next = table->buckets[hash]; 202 bucket->next = table->buckets[hash];
253 table->buckets[hash] = bucket; 203 table->buckets[hash] = bucket;
254#if HASH_DEBUG 204#if DEBUG
255 printf("Inserted %d at %d/%p\n", key, hash, bucket); 205 printf("Inserted %lu at %lu/%p\n", key, hash, bucket);
256#endif 206#endif
257 return 0; /* Added to table */ 207 return 0; /* Added to table */
258} 208}
@@ -270,7 +220,7 @@ int drmHashDelete(void *t, unsigned long key)
270 if (!bucket) return 1; /* Not found */ 220 if (!bucket) return 1; /* Not found */
271 221
272 table->buckets[hash] = bucket->next; 222 table->buckets[hash] = bucket->next;
273 HASH_FREE(bucket); 223 drmFree(bucket);
274 return 0; 224 return 0;
275} 225}
276 226
@@ -301,128 +251,3 @@ int drmHashFirst(void *t, unsigned long *key, void **value)
301 table->p1 = table->buckets[0]; 251 table->p1 = table->buckets[0];
302 return drmHashNext(table, key, value); 252 return drmHashNext(table, key, value);
303} 253}
304
305#if HASH_MAIN
306#define DIST_LIMIT 10
307static int dist[DIST_LIMIT];
308
309static void clear_dist(void) {
310 int i;
311
312 for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
313}
314
315static int count_entries(HashBucketPtr bucket)
316{
317 int count = 0;
318
319 for (; bucket; bucket = bucket->next) ++count;
320 return count;
321}
322
323static void update_dist(int count)
324{
325 if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
326 else ++dist[count];
327}
328
329static void compute_dist(HashTablePtr table)
330{
331 int i;
332 HashBucketPtr bucket;
333
334 printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
335 table->entries, table->hits, table->partials, table->misses);
336 clear_dist();
337 for (i = 0; i < HASH_SIZE; i++) {
338 bucket = table->buckets[i];
339 update_dist(count_entries(bucket));
340 }
341 for (i = 0; i < DIST_LIMIT; i++) {
342 if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
343 else printf("other %10d\n", dist[i]);
344 }
345}
346
347static void check_table(HashTablePtr table,
348 unsigned long key, unsigned long value)
349{
350 unsigned long retval = 0;
351 int retcode = drmHashLookup(table, key, &retval);
352
353 switch (retcode) {
354 case -1:
355 printf("Bad magic = 0x%08lx:"
356 " key = %lu, expected = %lu, returned = %lu\n",
357 table->magic, key, value, retval);
358 break;
359 case 1:
360 printf("Not found: key = %lu, expected = %lu returned = %lu\n",
361 key, value, retval);
362 break;
363 case 0:
364 if (value != retval)
365 printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
366 key, value, retval);
367 break;
368 default:
369 printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
370 retcode, key, value, retval);
371 break;
372 }
373}
374
375int main(void)
376{
377 HashTablePtr table;
378 int i;
379
380 printf("\n***** 256 consecutive integers ****\n");
381 table = drmHashCreate();
382 for (i = 0; i < 256; i++) drmHashInsert(table, i, i);
383 for (i = 0; i < 256; i++) check_table(table, i, i);
384 for (i = 256; i >= 0; i--) check_table(table, i, i);
385 compute_dist(table);
386 drmHashDestroy(table);
387
388 printf("\n***** 1024 consecutive integers ****\n");
389 table = drmHashCreate();
390 for (i = 0; i < 1024; i++) drmHashInsert(table, i, i);
391 for (i = 0; i < 1024; i++) check_table(table, i, i);
392 for (i = 1024; i >= 0; i--) check_table(table, i, i);
393 compute_dist(table);
394 drmHashDestroy(table);
395
396 printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
397 table = drmHashCreate();
398 for (i = 0; i < 1024; i++) drmHashInsert(table, i*4096, i);
399 for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
400 for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
401 compute_dist(table);
402 drmHashDestroy(table);
403
404 printf("\n***** 1024 random integers ****\n");
405 table = drmHashCreate();
406 srandom(0xbeefbeef);
407 for (i = 0; i < 1024; i++) drmHashInsert(table, random(), i);
408 srandom(0xbeefbeef);
409 for (i = 0; i < 1024; i++) check_table(table, random(), i);
410 srandom(0xbeefbeef);
411 for (i = 0; i < 1024; i++) check_table(table, random(), i);
412 compute_dist(table);
413 drmHashDestroy(table);
414
415 printf("\n***** 5000 random integers ****\n");
416 table = drmHashCreate();
417 srandom(0xbeefbeef);
418 for (i = 0; i < 5000; i++) drmHashInsert(table, random(), i);
419 srandom(0xbeefbeef);
420 for (i = 0; i < 5000; i++) check_table(table, random(), i);
421 srandom(0xbeefbeef);
422 for (i = 0; i < 5000; i++) check_table(table, random(), i);
423 compute_dist(table);
424 drmHashDestroy(table);
425
426 return 0;
427}
428#endif
diff --git a/xf86drmHash.h b/xf86drmHash.h
new file mode 100644
index 00000000..38fd84b7
--- /dev/null
+++ b/xf86drmHash.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
25 */
26
27#define HASH_SIZE 512 /* Good for about 100 entries */
28 /* If you change this value, you probably
29 have to change the HashHash hashing
30 function! */
31
32typedef struct HashBucket {
33 unsigned long key;
34 void *value;
35 struct HashBucket *next;
36} HashBucket, *HashBucketPtr;
37
38typedef struct HashTable {
39 unsigned long magic;
40 unsigned long entries;
41 unsigned long hits; /* At top of linked list */
42 unsigned long partials; /* Not at top of linked list */
43 unsigned long misses; /* Not in table */
44 HashBucketPtr buckets[HASH_SIZE];
45 int p0;
46 HashBucketPtr p1;
47} HashTable, *HashTablePtr;
diff --git a/xf86drmMode.c b/xf86drmMode.c
index e373c4cd..b341f382 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -37,15 +37,21 @@
37 * TODO the types we are after are defined in diffrent headers on diffrent 37 * TODO the types we are after are defined in diffrent headers on diffrent
38 * platforms find which headers to include to get uint32_t 38 * platforms find which headers to include to get uint32_t
39 */ 39 */
40#include <stdint.h>
41#include <sys/ioctl.h>
42#include <stdio.h>
43#include <stdbool.h>
44 40
45#ifdef HAVE_CONFIG_H 41#ifdef HAVE_CONFIG_H
46#include "config.h" 42#include "config.h"
47#endif 43#endif
48 44
45#include <limits.h>
46#include <stdint.h>
47#include <stdlib.h>
48#include <sys/ioctl.h>
49#ifdef HAVE_SYS_SYSCTL_H
50#include <sys/sysctl.h>
51#endif
52#include <stdio.h>
53#include <stdbool.h>
54
49#include "xf86drmMode.h" 55#include "xf86drmMode.h"
50#include "xf86drm.h" 56#include "xf86drm.h"
51#include <drm.h> 57#include <drm.h>
@@ -54,15 +60,7 @@
54#include <unistd.h> 60#include <unistd.h>
55#include <errno.h> 61#include <errno.h>
56 62
57#ifdef HAVE_VALGRIND 63#define memclear(s) memset(&s, 0, sizeof(s))
58#include <valgrind.h>
59#include <memcheck.h>
60#define VG(x) x
61#else
62#define VG(x)
63#endif
64
65#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
66 64
67#define U642VOID(x) ((void *)(unsigned long)(x)) 65#define U642VOID(x) ((void *)(unsigned long)(x))
68#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) 66#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
@@ -77,7 +75,7 @@ static inline int DRM_IOCTL(int fd, unsigned long cmd, void *arg)
77 * Util functions 75 * Util functions
78 */ 76 */
79 77
80void* drmAllocCpy(void *array, int count, int entry_size) 78static void* drmAllocCpy(char *array, int count, int entry_size)
81{ 79{
82 char *r; 80 char *r;
83 int i; 81 int i;
@@ -116,7 +114,6 @@ void drmModeFreeResources(drmModeResPtr ptr)
116 drmFree(ptr->connectors); 114 drmFree(ptr->connectors);
117 drmFree(ptr->encoders); 115 drmFree(ptr->encoders);
118 drmFree(ptr); 116 drmFree(ptr);
119
120} 117}
121 118
122void drmModeFreeFB(drmModeFBPtr ptr) 119void drmModeFreeFB(drmModeFBPtr ptr)
@@ -134,7 +131,6 @@ void drmModeFreeCrtc(drmModeCrtcPtr ptr)
134 return; 131 return;
135 132
136 drmFree(ptr); 133 drmFree(ptr);
137
138} 134}
139 135
140void drmModeFreeConnector(drmModeConnectorPtr ptr) 136void drmModeFreeConnector(drmModeConnectorPtr ptr)
@@ -147,7 +143,6 @@ void drmModeFreeConnector(drmModeConnectorPtr ptr)
147 drmFree(ptr->props); 143 drmFree(ptr->props);
148 drmFree(ptr->modes); 144 drmFree(ptr->modes);
149 drmFree(ptr); 145 drmFree(ptr);
150
151} 146}
152 147
153void drmModeFreeEncoder(drmModeEncoderPtr ptr) 148void drmModeFreeEncoder(drmModeEncoderPtr ptr)
@@ -165,7 +160,7 @@ drmModeResPtr drmModeGetResources(int fd)
165 drmModeResPtr r = 0; 160 drmModeResPtr r = 0;
166 161
167retry: 162retry:
168 memset(&res, 0, sizeof(struct drm_mode_card_res)); 163 memclear(res);
169 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) 164 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
170 return 0; 165 return 0;
171 166
@@ -254,13 +249,13 @@ err_allocs:
254} 249}
255 250
256int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, 251int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
257 uint8_t bpp, uint32_t pitch, uint32_t bo_handle, 252 uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
258 uint32_t *buf_id) 253 uint32_t *buf_id)
259{ 254{
260 struct drm_mode_fb_cmd f; 255 struct drm_mode_fb_cmd f;
261 int ret; 256 int ret;
262 257
263 VG_CLEAR(f); 258 memclear(f);
264 f.width = width; 259 f.width = width;
265 f.height = height; 260 f.height = height;
266 f.pitch = pitch; 261 f.pitch = pitch;
@@ -283,6 +278,7 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
283 struct drm_mode_fb_cmd2 f; 278 struct drm_mode_fb_cmd2 f;
284 int ret; 279 int ret;
285 280
281 memclear(f);
286 f.width = width; 282 f.width = width;
287 f.height = height; 283 f.height = height;
288 f.pixel_format = pixel_format; 284 f.pixel_format = pixel_format;
@@ -301,8 +297,6 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
301int drmModeRmFB(int fd, uint32_t bufferId) 297int drmModeRmFB(int fd, uint32_t bufferId)
302{ 298{
303 return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId); 299 return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
304
305
306} 300}
307 301
308drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) 302drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
@@ -310,6 +304,7 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
310 struct drm_mode_fb_cmd info; 304 struct drm_mode_fb_cmd info;
311 drmModeFBPtr r; 305 drmModeFBPtr r;
312 306
307 memclear(info);
313 info.fb_id = buf; 308 info.fb_id = buf;
314 309
315 if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info)) 310 if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info))
@@ -332,8 +327,9 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
332int drmModeDirtyFB(int fd, uint32_t bufferId, 327int drmModeDirtyFB(int fd, uint32_t bufferId,
333 drmModeClipPtr clips, uint32_t num_clips) 328 drmModeClipPtr clips, uint32_t num_clips)
334{ 329{
335 struct drm_mode_fb_dirty_cmd dirty = { 0 }; 330 struct drm_mode_fb_dirty_cmd dirty;
336 331
332 memclear(dirty);
337 dirty.fb_id = bufferId; 333 dirty.fb_id = bufferId;
338 dirty.clips_ptr = VOID2U64(clips); 334 dirty.clips_ptr = VOID2U64(clips);
339 dirty.num_clips = num_clips; 335 dirty.num_clips = num_clips;
@@ -341,7 +337,6 @@ int drmModeDirtyFB(int fd, uint32_t bufferId,
341 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); 337 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty);
342} 338}
343 339
344
345/* 340/*
346 * Crtc functions 341 * Crtc functions
347 */ 342 */
@@ -351,7 +346,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
351 struct drm_mode_crtc crtc; 346 struct drm_mode_crtc crtc;
352 drmModeCrtcPtr r; 347 drmModeCrtcPtr r;
353 348
354 VG_CLEAR(crtc); 349 memclear(crtc);
355 crtc.crtc_id = crtcId; 350 crtc.crtc_id = crtcId;
356 351
357 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc)) 352 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
@@ -378,14 +373,13 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
378 return r; 373 return r;
379} 374}
380 375
381
382int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, 376int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
383 uint32_t x, uint32_t y, uint32_t *connectors, int count, 377 uint32_t x, uint32_t y, uint32_t *connectors, int count,
384 drmModeModeInfoPtr mode) 378 drmModeModeInfoPtr mode)
385{ 379{
386 struct drm_mode_crtc crtc; 380 struct drm_mode_crtc crtc;
387 381
388 VG_CLEAR(crtc); 382 memclear(crtc);
389 crtc.x = x; 383 crtc.x = x;
390 crtc.y = y; 384 crtc.y = y;
391 crtc.crtc_id = crtcId; 385 crtc.crtc_id = crtcId;
@@ -395,8 +389,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
395 if (mode) { 389 if (mode) {
396 memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo)); 390 memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo));
397 crtc.mode_valid = 1; 391 crtc.mode_valid = 1;
398 } else 392 }
399 crtc.mode_valid = 0;
400 393
401 return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); 394 return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
402} 395}
@@ -409,6 +402,7 @@ int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width
409{ 402{
410 struct drm_mode_cursor arg; 403 struct drm_mode_cursor arg;
411 404
405 memclear(arg);
412 arg.flags = DRM_MODE_CURSOR_BO; 406 arg.flags = DRM_MODE_CURSOR_BO;
413 arg.crtc_id = crtcId; 407 arg.crtc_id = crtcId;
414 arg.width = width; 408 arg.width = width;
@@ -422,6 +416,7 @@ int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t widt
422{ 416{
423 struct drm_mode_cursor2 arg; 417 struct drm_mode_cursor2 arg;
424 418
419 memclear(arg);
425 arg.flags = DRM_MODE_CURSOR_BO; 420 arg.flags = DRM_MODE_CURSOR_BO;
426 arg.crtc_id = crtcId; 421 arg.crtc_id = crtcId;
427 arg.width = width; 422 arg.width = width;
@@ -437,6 +432,7 @@ int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
437{ 432{
438 struct drm_mode_cursor arg; 433 struct drm_mode_cursor arg;
439 434
435 memclear(arg);
440 arg.flags = DRM_MODE_CURSOR_MOVE; 436 arg.flags = DRM_MODE_CURSOR_MOVE;
441 arg.crtc_id = crtcId; 437 arg.crtc_id = crtcId;
442 arg.x = x; 438 arg.x = x;
@@ -453,11 +449,8 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
453 struct drm_mode_get_encoder enc; 449 struct drm_mode_get_encoder enc;
454 drmModeEncoderPtr r = NULL; 450 drmModeEncoderPtr r = NULL;
455 451
452 memclear(enc);
456 enc.encoder_id = encoder_id; 453 enc.encoder_id = encoder_id;
457 enc.crtc_id = 0;
458 enc.encoder_type = 0;
459 enc.possible_crtcs = 0;
460 enc.possible_clones = 0;
461 454
462 if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc)) 455 if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc))
463 return 0; 456 return 0;
@@ -477,19 +470,23 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
477/* 470/*
478 * Connector manipulation 471 * Connector manipulation
479 */ 472 */
480 473static drmModeConnectorPtr
481drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) 474_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
482{ 475{
483 struct drm_mode_get_connector conn, counts; 476 struct drm_mode_get_connector conn, counts;
484 drmModeConnectorPtr r = NULL; 477 drmModeConnectorPtr r = NULL;
485 478
486retry: 479 memclear(conn);
487 memset(&conn, 0, sizeof(struct drm_mode_get_connector));
488 conn.connector_id = connector_id; 480 conn.connector_id = connector_id;
481 if (!probe) {
482 conn.count_modes = 1;
483 conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
484 }
489 485
490 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) 486 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
491 return 0; 487 return 0;
492 488
489retry:
493 counts = conn; 490 counts = conn;
494 491
495 if (conn.count_props) { 492 if (conn.count_props) {
@@ -505,6 +502,9 @@ retry:
505 conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo))); 502 conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
506 if (!conn.modes_ptr) 503 if (!conn.modes_ptr)
507 goto err_allocs; 504 goto err_allocs;
505 } else {
506 conn.count_modes = 1;
507 conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
508 } 508 }
509 509
510 if (conn.count_encoders) { 510 if (conn.count_encoders) {
@@ -573,10 +573,21 @@ err_allocs:
573 return r; 573 return r;
574} 574}
575 575
576drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
577{
578 return _drmModeGetConnector(fd, connector_id, 1);
579}
580
581drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
582{
583 return _drmModeGetConnector(fd, connector_id, 0);
584}
585
576int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info) 586int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
577{ 587{
578 struct drm_mode_mode_cmd res; 588 struct drm_mode_mode_cmd res;
579 589
590 memclear(res);
580 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); 591 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
581 res.connector_id = connector_id; 592 res.connector_id = connector_id;
582 593
@@ -587,25 +598,20 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf
587{ 598{
588 struct drm_mode_mode_cmd res; 599 struct drm_mode_mode_cmd res;
589 600
601 memclear(res);
590 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); 602 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
591 res.connector_id = connector_id; 603 res.connector_id = connector_id;
592 604
593 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res); 605 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
594} 606}
595 607
596
597drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) 608drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
598{ 609{
599 struct drm_mode_get_property prop; 610 struct drm_mode_get_property prop;
600 drmModePropertyPtr r; 611 drmModePropertyPtr r;
601 612
602 VG_CLEAR(prop); 613 memclear(prop);
603 prop.prop_id = property_id; 614 prop.prop_id = property_id;
604 prop.count_enum_blobs = 0;
605 prop.count_values = 0;
606 prop.flags = 0;
607 prop.enum_blob_ptr = 0;
608 prop.values_ptr = 0;
609 615
610 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) 616 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
611 return 0; 617 return 0;
@@ -668,8 +674,7 @@ drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
668 struct drm_mode_get_blob blob; 674 struct drm_mode_get_blob blob;
669 drmModePropertyBlobPtr r; 675 drmModePropertyBlobPtr r;
670 676
671 blob.length = 0; 677 memclear(blob);
672 blob.data = 0;
673 blob.blob_id = blob_id; 678 blob.blob_id = blob_id;
674 679
675 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) 680 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
@@ -709,6 +714,7 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property
709{ 714{
710 struct drm_mode_connector_set_property osp; 715 struct drm_mode_connector_set_property osp;
711 716
717 memclear(osp);
712 osp.connector_id = connector_id; 718 osp.connector_id = connector_id;
713 osp.prop_id = property_id; 719 osp.prop_id = property_id;
714 osp.value = value; 720 osp.value = value;
@@ -810,8 +816,25 @@ int drmCheckModesettingSupported(const char *busid)
810#elif defined(__DragonFly__) 816#elif defined(__DragonFly__)
811 return 0; 817 return 0;
812#endif 818#endif
813 return -ENOSYS; 819#ifdef __OpenBSD__
820 int fd;
821 struct drm_mode_card_res res;
822 drmModeResPtr r = 0;
814 823
824 if ((fd = drmOpen(NULL, busid)) < 0)
825 return -EINVAL;
826
827 memset(&res, 0, sizeof(struct drm_mode_card_res));
828
829 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
830 drmClose(fd);
831 return -errno;
832 }
833
834 drmClose(fd);
835 return 0;
836#endif
837 return -ENOSYS;
815} 838}
816 839
817int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, 840int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
@@ -819,6 +842,7 @@ int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
819{ 842{
820 struct drm_mode_crtc_lut l; 843 struct drm_mode_crtc_lut l;
821 844
845 memclear(l);
822 l.crtc_id = crtc_id; 846 l.crtc_id = crtc_id;
823 l.gamma_size = size; 847 l.gamma_size = size;
824 l.red = VOID2U64(red); 848 l.red = VOID2U64(red);
@@ -833,6 +857,7 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
833{ 857{
834 struct drm_mode_crtc_lut l; 858 struct drm_mode_crtc_lut l;
835 859
860 memclear(l);
836 l.crtc_id = crtc_id; 861 l.crtc_id = crtc_id;
837 l.gamma_size = size; 862 l.gamma_size = size;
838 l.red = VOID2U64(red); 863 l.red = VOID2U64(red);
@@ -848,14 +873,14 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
848 int len, i; 873 int len, i;
849 struct drm_event *e; 874 struct drm_event *e;
850 struct drm_event_vblank *vblank; 875 struct drm_event_vblank *vblank;
851 876
852 /* The DRM read semantics guarantees that we always get only 877 /* The DRM read semantics guarantees that we always get only
853 * complete events. */ 878 * complete events. */
854 879
855 len = read(fd, buffer, sizeof buffer); 880 len = read(fd, buffer, sizeof buffer);
856 if (len == 0) 881 if (len == 0)
857 return 0; 882 return 0;
858 if (len < sizeof *e) 883 if (len < (int)sizeof *e)
859 return -1; 884 return -1;
860 885
861 i = 0; 886 i = 0;
@@ -868,7 +893,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
868 break; 893 break;
869 vblank = (struct drm_event_vblank *) e; 894 vblank = (struct drm_event_vblank *) e;
870 evctx->vblank_handler(fd, 895 evctx->vblank_handler(fd,
871 vblank->sequence, 896 vblank->sequence,
872 vblank->tv_sec, 897 vblank->tv_sec,
873 vblank->tv_usec, 898 vblank->tv_usec,
874 U642VOID (vblank->user_data)); 899 U642VOID (vblank->user_data));
@@ -898,11 +923,11 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
898{ 923{
899 struct drm_mode_crtc_page_flip flip; 924 struct drm_mode_crtc_page_flip flip;
900 925
926 memclear(flip);
901 flip.fb_id = fb_id; 927 flip.fb_id = fb_id;
902 flip.crtc_id = crtc_id; 928 flip.crtc_id = crtc_id;
903 flip.user_data = VOID2U64(user_data); 929 flip.user_data = VOID2U64(user_data);
904 flip.flags = flags; 930 flip.flags = flags;
905 flip.reserved = 0;
906 931
907 return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); 932 return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
908} 933}
@@ -913,10 +938,10 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
913 uint32_t crtc_w, uint32_t crtc_h, 938 uint32_t crtc_w, uint32_t crtc_h,
914 uint32_t src_x, uint32_t src_y, 939 uint32_t src_x, uint32_t src_y,
915 uint32_t src_w, uint32_t src_h) 940 uint32_t src_w, uint32_t src_h)
916
917{ 941{
918 struct drm_mode_set_plane s; 942 struct drm_mode_set_plane s;
919 943
944 memclear(s);
920 s.plane_id = plane_id; 945 s.plane_id = plane_id;
921 s.crtc_id = crtc_id; 946 s.crtc_id = crtc_id;
922 s.fb_id = fb_id; 947 s.fb_id = fb_id;
@@ -933,14 +958,13 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
933 return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s); 958 return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s);
934} 959}
935 960
936
937drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) 961drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
938{ 962{
939 struct drm_mode_get_plane ovr, counts; 963 struct drm_mode_get_plane ovr, counts;
940 drmModePlanePtr r = 0; 964 drmModePlanePtr r = 0;
941 965
942retry: 966retry:
943 memset(&ovr, 0, sizeof(struct drm_mode_get_plane)); 967 memclear(ovr);
944 ovr.plane_id = plane_id; 968 ovr.plane_id = plane_id;
945 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) 969 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
946 return 0; 970 return 0;
@@ -1000,7 +1024,7 @@ drmModePlaneResPtr drmModeGetPlaneResources(int fd)
1000 drmModePlaneResPtr r = 0; 1024 drmModePlaneResPtr r = 0;
1001 1025
1002retry: 1026retry:
1003 memset(&res, 0, sizeof(struct drm_mode_get_plane_res)); 1027 memclear(res);
1004 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) 1028 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res))
1005 return 0; 1029 return 0;
1006 1030
@@ -1057,7 +1081,7 @@ drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd,
1057 uint32_t count; 1081 uint32_t count;
1058 1082
1059retry: 1083retry:
1060 memset(&properties, 0, sizeof(struct drm_mode_obj_get_properties)); 1084 memclear(properties);
1061 properties.obj_id = object_id; 1085 properties.obj_id = object_id;
1062 properties.obj_type = object_type; 1086 properties.obj_type = object_type;
1063 1087
@@ -1123,6 +1147,7 @@ int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
1123{ 1147{
1124 struct drm_mode_obj_set_property prop; 1148 struct drm_mode_obj_set_property prop;
1125 1149
1150 memclear(prop);
1126 prop.value = value; 1151 prop.value = value;
1127 prop.prop_id = property_id; 1152 prop.prop_id = property_id;
1128 prop.obj_id = object_id; 1153 prop.obj_id = object_id;
@@ -1399,3 +1424,293 @@ out:
1399 1424
1400 return ret; 1425 return ret;
1401} 1426}
1427
1428typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr;
1429
1430struct _drmModeAtomicReqItem {
1431 uint32_t object_id;
1432 uint32_t property_id;
1433 uint64_t value;
1434};
1435
1436struct _drmModeAtomicReq {
1437 uint32_t cursor;
1438 uint32_t size_items;
1439 drmModeAtomicReqItemPtr items;
1440};
1441
1442drmModeAtomicReqPtr drmModeAtomicAlloc(void)
1443{
1444 drmModeAtomicReqPtr req;
1445
1446 req = drmMalloc(sizeof *req);
1447 if (!req)
1448 return NULL;
1449
1450 req->items = NULL;
1451 req->cursor = 0;
1452 req->size_items = 0;
1453
1454 return req;
1455}
1456
1457drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
1458{
1459 drmModeAtomicReqPtr new;
1460
1461 if (!old)
1462 return NULL;
1463
1464 new = drmMalloc(sizeof *new);
1465 if (!new)
1466 return NULL;
1467
1468 new->cursor = old->cursor;
1469 new->size_items = old->size_items;
1470
1471 if (old->size_items) {
1472 new->items = drmMalloc(old->size_items * sizeof(*new->items));
1473 if (!new->items) {
1474 free(new);
1475 return NULL;
1476 }
1477 memcpy(new->items, old->items,
1478 old->size_items * sizeof(*new->items));
1479 } else {
1480 new->items = NULL;
1481 }
1482
1483 return new;
1484}
1485
1486int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment)
1487{
1488 if (!base)
1489 return -EINVAL;
1490
1491 if (!augment || augment->cursor == 0)
1492 return 0;
1493
1494 if (base->cursor + augment->cursor >= base->size_items) {
1495 drmModeAtomicReqItemPtr new;
1496 int saved_size = base->size_items;
1497
1498 base->size_items = base->cursor + augment->cursor;
1499 new = realloc(base->items,
1500 base->size_items * sizeof(*base->items));
1501 if (!new) {
1502 base->size_items = saved_size;
1503 return -ENOMEM;
1504 }
1505 base->items = new;
1506 }
1507
1508 memcpy(&base->items[base->cursor], augment->items,
1509 augment->cursor * sizeof(*augment->items));
1510 base->cursor += augment->cursor;
1511
1512 return 0;
1513}
1514
1515int drmModeAtomicGetCursor(drmModeAtomicReqPtr req)
1516{
1517 if (!req)
1518 return -EINVAL;
1519 return req->cursor;
1520}
1521
1522void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor)
1523{
1524 if (req)
1525 req->cursor = cursor;
1526}
1527
1528int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
1529 uint32_t object_id,
1530 uint32_t property_id,
1531 uint64_t value)
1532{
1533 if (!req)
1534 return -EINVAL;
1535
1536 if (req->cursor >= req->size_items) {
1537 drmModeAtomicReqItemPtr new;
1538
1539 req->size_items += 16;
1540 new = realloc(req->items, req->size_items * sizeof(*req->items));
1541 if (!new) {
1542 req->size_items -= 16;
1543 return -ENOMEM;
1544 }
1545 req->items = new;
1546 }
1547
1548 req->items[req->cursor].object_id = object_id;
1549 req->items[req->cursor].property_id = property_id;
1550 req->items[req->cursor].value = value;
1551 req->cursor++;
1552
1553 return req->cursor;
1554}
1555
1556void drmModeAtomicFree(drmModeAtomicReqPtr req)
1557{
1558 if (!req)
1559 return;
1560
1561 if (req->items)
1562 drmFree(req->items);
1563 drmFree(req);
1564}
1565
1566static int sort_req_list(const void *misc, const void *other)
1567{
1568 const drmModeAtomicReqItem *first = misc;
1569 const drmModeAtomicReqItem *second = other;
1570
1571 if (first->object_id < second->object_id)
1572 return -1;
1573 else if (first->object_id > second->object_id)
1574 return 1;
1575 else
1576 return second->property_id - first->property_id;
1577}
1578
1579int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags,
1580 void *user_data)
1581{
1582 drmModeAtomicReqPtr sorted;
1583 struct drm_mode_atomic atomic;
1584 uint32_t *objs_ptr = NULL;
1585 uint32_t *count_props_ptr = NULL;
1586 uint32_t *props_ptr = NULL;
1587 uint64_t *prop_values_ptr = NULL;
1588 uint32_t last_obj_id = 0;
1589 uint32_t i;
1590 int obj_idx = -1;
1591 int ret = -1;
1592
1593 if (!req)
1594 return -EINVAL;
1595
1596 if (req->cursor == 0)
1597 return 0;
1598
1599 sorted = drmModeAtomicDuplicate(req);
1600 if (sorted == NULL)
1601 return -ENOMEM;
1602
1603 memclear(atomic);
1604
1605 /* Sort the list by object ID, then by property ID. */
1606 qsort(sorted->items, sorted->cursor, sizeof(*sorted->items),
1607 sort_req_list);
1608
1609 /* Now the list is sorted, eliminate duplicate property sets. */
1610 for (i = 0; i < sorted->cursor; i++) {
1611 if (sorted->items[i].object_id != last_obj_id) {
1612 atomic.count_objs++;
1613 last_obj_id = sorted->items[i].object_id;
1614 }
1615
1616 if (i == sorted->cursor - 1)
1617 continue;
1618
1619 if (sorted->items[i].object_id != sorted->items[i + 1].object_id ||
1620 sorted->items[i].property_id != sorted->items[i + 1].property_id)
1621 continue;
1622
1623 memmove(&sorted->items[i], &sorted->items[i + 1],
1624 (sorted->cursor - i - 1) * sizeof(*sorted->items));
1625 sorted->cursor--;
1626 }
1627
1628 objs_ptr = drmMalloc(atomic.count_objs * sizeof objs_ptr[0]);
1629 if (!objs_ptr) {
1630 errno = ENOMEM;
1631 goto out;
1632 }
1633
1634 count_props_ptr = drmMalloc(atomic.count_objs * sizeof count_props_ptr[0]);
1635 if (!count_props_ptr) {
1636 errno = ENOMEM;
1637 goto out;
1638 }
1639
1640 props_ptr = drmMalloc(sorted->cursor * sizeof props_ptr[0]);
1641 if (!props_ptr) {
1642 errno = ENOMEM;
1643 goto out;
1644 }
1645
1646 prop_values_ptr = drmMalloc(sorted->cursor * sizeof prop_values_ptr[0]);
1647 if (!prop_values_ptr) {
1648 errno = ENOMEM;
1649 goto out;
1650 }
1651
1652 for (i = 0, last_obj_id = 0; i < sorted->cursor; i++) {
1653 if (sorted->items[i].object_id != last_obj_id) {
1654 obj_idx++;
1655 objs_ptr[obj_idx] = sorted->items[i].object_id;
1656 last_obj_id = objs_ptr[obj_idx];
1657 }
1658
1659 count_props_ptr[obj_idx]++;
1660 props_ptr[i] = sorted->items[i].property_id;
1661 prop_values_ptr[i] = sorted->items[i].value;
1662
1663 }
1664
1665 atomic.flags = flags;
1666 atomic.objs_ptr = VOID2U64(objs_ptr);
1667 atomic.count_props_ptr = VOID2U64(count_props_ptr);
1668 atomic.props_ptr = VOID2U64(props_ptr);
1669 atomic.prop_values_ptr = VOID2U64(prop_values_ptr);
1670 atomic.user_data = VOID2U64(user_data);
1671
1672 ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic);
1673
1674out:
1675 drmFree(objs_ptr);
1676 drmFree(count_props_ptr);
1677 drmFree(props_ptr);
1678 drmFree(prop_values_ptr);
1679 drmModeAtomicFree(sorted);
1680
1681 return ret;
1682}
1683
1684int
1685drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
1686{
1687 struct drm_mode_create_blob create;
1688 int ret;
1689
1690 if (length >= 0xffffffff)
1691 return -ERANGE;
1692
1693 memclear(create);
1694
1695 create.length = length;
1696 create.data = (uintptr_t) data;
1697 create.blob_id = 0;
1698 *id = 0;
1699
1700 ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create);
1701 if (ret != 0)
1702 return ret;
1703
1704 *id = create.blob_id;
1705 return 0;
1706}
1707
1708int
1709drmModeDestroyPropertyBlob(int fd, uint32_t id)
1710{
1711 struct drm_mode_destroy_blob destroy;
1712
1713 memclear(destroy);
1714 destroy.blob_id = id;
1715 return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
1716}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 02c94b30..53bb423c 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -36,7 +36,7 @@
36#ifndef _XF86DRMMODE_H_ 36#ifndef _XF86DRMMODE_H_
37#define _XF86DRMMODE_H_ 37#define _XF86DRMMODE_H_
38 38
39#if defined(__cplusplus) || defined(c_plusplus) 39#if defined(__cplusplus)
40extern "C" { 40extern "C" {
41#endif 41#endif
42 42
@@ -240,7 +240,7 @@ typedef struct _drmModeProperty {
240 uint32_t *blob_ids; /* store the blob IDs */ 240 uint32_t *blob_ids; /* store the blob IDs */
241} drmModePropertyRes, *drmModePropertyPtr; 241} drmModePropertyRes, *drmModePropertyPtr;
242 242
243static inline int drm_property_type_is(drmModePropertyPtr property, 243static __inline int drm_property_type_is(drmModePropertyPtr property,
244 uint32_t type) 244 uint32_t type)
245{ 245{
246 /* instanceof for props.. handles extended type vs original types: */ 246 /* instanceof for props.. handles extended type vs original types: */
@@ -422,10 +422,23 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id);
422 */ 422 */
423 423
424/** 424/**
425 * Retrive information about the connector connectorId. 425 * Retrieve all information about the connector connectorId. This will do a
426 * forced probe on the connector to retrieve remote information such as EDIDs
427 * from the display device.
426 */ 428 */
427extern drmModeConnectorPtr drmModeGetConnector(int fd, 429extern drmModeConnectorPtr drmModeGetConnector(int fd,
428 uint32_t connectorId); 430 uint32_t connectorId);
431
432/**
433 * Retrieve current information, i.e the currently active mode and encoder,
434 * about the connector connectorId. This will not do any probing on the
435 * connector or remote device, and only reports what is currently known.
436 * For the complete set of modes and encoders associated with the connector
437 * use drmModeGetConnector() which will do a probe to determine any display
438 * link changes first.
439 */
440extern drmModeConnectorPtr drmModeGetConnectorCurrent(int fd,
441 uint32_t connector_id);
429 442
430/** 443/**
431 * Attaches the given mode to an connector. 444 * Attaches the given mode to an connector.
@@ -491,7 +504,30 @@ extern int drmModePropertySetCommit(int fd, uint32_t flags,
491 504
492extern void drmModePropertySetFree(drmModePropertySetPtr set); 505extern void drmModePropertySetFree(drmModePropertySetPtr set);
493 506
494#if defined(__cplusplus) || defined(c_plusplus) 507typedef struct _drmModeAtomicReq drmModeAtomicReq, *drmModeAtomicReqPtr;
508
509extern drmModeAtomicReqPtr drmModeAtomicAlloc(void);
510extern drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr req);
511extern int drmModeAtomicMerge(drmModeAtomicReqPtr base,
512 drmModeAtomicReqPtr augment);
513extern void drmModeAtomicFree(drmModeAtomicReqPtr req);
514extern int drmModeAtomicGetCursor(drmModeAtomicReqPtr req);
515extern void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor);
516extern int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
517 uint32_t object_id,
518 uint32_t property_id,
519 uint64_t value);
520extern int drmModeAtomicCommit(int fd,
521 drmModeAtomicReqPtr req,
522 uint32_t flags,
523 void *user_data);
524
525extern int drmModeCreatePropertyBlob(int fd, const void *data, size_t size,
526 uint32_t *id);
527extern int drmModeDestroyPropertyBlob(int fd, uint32_t id);
528
529
530#if defined(__cplusplus)
495} 531}
496#endif 532#endif
497 533
diff --git a/xf86drmRandom.c b/xf86drmRandom.c
index ecab9e2d..81f03014 100644
--- a/xf86drmRandom.c
+++ b/xf86drmRandom.c
@@ -74,45 +74,16 @@
74#include <stdio.h> 74#include <stdio.h>
75#include <stdlib.h> 75#include <stdlib.h>
76 76
77#define RANDOM_MAIN 0 77#include "xf86drm.h"
78 78#include "xf86drmRandom.h"
79#if !RANDOM_MAIN
80# include "xf86drm.h"
81#endif
82 79
83#define RANDOM_MAGIC 0xfeedbeef 80#define RANDOM_MAGIC 0xfeedbeef
84#define RANDOM_DEBUG 0
85
86#if RANDOM_MAIN
87#define RANDOM_ALLOC malloc
88#define RANDOM_FREE free
89#else
90#define RANDOM_ALLOC drmMalloc
91#define RANDOM_FREE drmFree
92#endif
93
94typedef struct RandomState {
95 unsigned long magic;
96 unsigned long a;
97 unsigned long m;
98 unsigned long q; /* m div a */
99 unsigned long r; /* m mod a */
100 unsigned long check;
101 long seed;
102} RandomState;
103
104#if RANDOM_MAIN
105extern void *drmRandomCreate(unsigned long seed);
106extern int drmRandomDestroy(void *state);
107extern unsigned long drmRandom(void *state);
108extern double drmRandomDouble(void *state);
109#endif
110 81
111void *drmRandomCreate(unsigned long seed) 82void *drmRandomCreate(unsigned long seed)
112{ 83{
113 RandomState *state; 84 RandomState *state;
114 85
115 state = RANDOM_ALLOC(sizeof(*state)); 86 state = drmMalloc(sizeof(*state));
116 if (!state) return NULL; 87 if (!state) return NULL;
117 state->magic = RANDOM_MAGIC; 88 state->magic = RANDOM_MAGIC;
118#if 0 89#if 0
@@ -140,20 +111,20 @@ void *drmRandomCreate(unsigned long seed)
140 111
141int drmRandomDestroy(void *state) 112int drmRandomDestroy(void *state)
142{ 113{
143 RANDOM_FREE(state); 114 drmFree(state);
144 return 0; 115 return 0;
145} 116}
146 117
147unsigned long drmRandom(void *state) 118unsigned long drmRandom(void *state)
148{ 119{
149 RandomState *s = (RandomState *)state; 120 RandomState *s = (RandomState *)state;
150 long hi; 121 unsigned long hi;
151 long lo; 122 unsigned long lo;
152 123
153 hi = s->seed / s->q; 124 hi = s->seed / s->q;
154 lo = s->seed % s->q; 125 lo = s->seed % s->q;
155 s->seed = s->a * lo - s->r * hi; 126 s->seed = s->a * lo - s->r * hi;
156 if (s->seed <= 0) s->seed += s->m; 127 if ((s->a * lo) <= (s->r * hi)) s->seed += s->m;
157 128
158 return s->seed; 129 return s->seed;
159} 130}
@@ -164,45 +135,3 @@ double drmRandomDouble(void *state)
164 135
165 return (double)drmRandom(state)/(double)s->m; 136 return (double)drmRandom(state)/(double)s->m;
166} 137}
167
168#if RANDOM_MAIN
169static void check_period(long seed)
170{
171 unsigned long count = 0;
172 unsigned long initial;
173 void *state;
174
175 state = drmRandomCreate(seed);
176 initial = drmRandom(state);
177 ++count;
178 while (initial != drmRandom(state)) {
179 if (!++count) break;
180 }
181 printf("With seed of %10ld, period = %10lu (0x%08lx)\n",
182 seed, count, count);
183 drmRandomDestroy(state);
184}
185
186int main(void)
187{
188 RandomState *state;
189 int i;
190 unsigned long rand;
191
192 state = drmRandomCreate(1);
193 for (i = 0; i < 10000; i++) {
194 rand = drmRandom(state);
195 }
196 printf("After 10000 iterations: %lu (%lu expected): %s\n",
197 rand, state->check,
198 rand - state->check ? "*INCORRECT*" : "CORRECT");
199 drmRandomDestroy(state);
200
201 printf("Checking periods...\n");
202 check_period(1);
203 check_period(2);
204 check_period(31415926);
205
206 return 0;
207}
208#endif
diff --git a/xf86drmRandom.h b/xf86drmRandom.h
new file mode 100644
index 00000000..43b730ce
--- /dev/null
+++ b/xf86drmRandom.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
25 */
26
27typedef struct RandomState {
28 unsigned long magic;
29 unsigned long a;
30 unsigned long m;
31 unsigned long q; /* m div a */
32 unsigned long r; /* m mod a */
33 unsigned long check;
34 unsigned long seed;
35} RandomState;
diff --git a/xf86drmSL.c b/xf86drmSL.c
index acddb541..a12fa1d0 100644
--- a/xf86drmSL.c
+++ b/xf86drmSL.c
@@ -41,36 +41,18 @@
41#include <stdio.h> 41#include <stdio.h>
42#include <stdlib.h> 42#include <stdlib.h>
43 43
44#define SL_MAIN 0 44#include "xf86drm.h"
45
46#if !SL_MAIN
47# include "xf86drm.h"
48#else
49# include <sys/time.h>
50#endif
51 45
52#define SL_LIST_MAGIC 0xfacade00LU 46#define SL_LIST_MAGIC 0xfacade00LU
53#define SL_ENTRY_MAGIC 0x00fab1edLU 47#define SL_ENTRY_MAGIC 0x00fab1edLU
54#define SL_FREED_MAGIC 0xdecea5edLU 48#define SL_FREED_MAGIC 0xdecea5edLU
55#define SL_MAX_LEVEL 16 49#define SL_MAX_LEVEL 16
56#define SL_DEBUG 0
57#define SL_RANDOM_SEED 0xc01055a1LU 50#define SL_RANDOM_SEED 0xc01055a1LU
58 51
59#if SL_MAIN
60#define SL_ALLOC malloc
61#define SL_FREE free
62#define SL_RANDOM_DECL static int state = 0;
63#define SL_RANDOM_INIT(seed) if (!state) { srandom(seed); ++state; }
64#define SL_RANDOM random()
65#else
66#define SL_ALLOC drmMalloc
67#define SL_FREE drmFree
68#define SL_RANDOM_DECL static void *state = NULL 52#define SL_RANDOM_DECL static void *state = NULL
69#define SL_RANDOM_INIT(seed) if (!state) state = drmRandomCreate(seed) 53#define SL_RANDOM_INIT(seed) if (!state) state = drmRandomCreate(seed)
70#define SL_RANDOM drmRandom(state) 54#define SL_RANDOM drmRandom(state)
71 55
72#endif
73
74typedef struct SLEntry { 56typedef struct SLEntry {
75 unsigned long magic; /* SL_ENTRY_MAGIC */ 57 unsigned long magic; /* SL_ENTRY_MAGIC */
76 unsigned long key; 58 unsigned long key;
@@ -87,27 +69,13 @@ typedef struct SkipList {
87 SLEntryPtr p0; /* Position for iteration */ 69 SLEntryPtr p0; /* Position for iteration */
88} SkipList, *SkipListPtr; 70} SkipList, *SkipListPtr;
89 71
90#if SL_MAIN
91extern void *drmSLCreate(void);
92extern int drmSLDestroy(void *l);
93extern int drmSLLookup(void *l, unsigned long key, void **value);
94extern int drmSLInsert(void *l, unsigned long key, void *value);
95extern int drmSLDelete(void *l, unsigned long key);
96extern int drmSLNext(void *l, unsigned long *key, void **value);
97extern int drmSLFirst(void *l, unsigned long *key, void **value);
98extern void drmSLDump(void *l);
99extern int drmSLLookupNeighbors(void *l, unsigned long key,
100 unsigned long *prev_key, void **prev_value,
101 unsigned long *next_key, void **next_value);
102#endif
103
104static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value) 72static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value)
105{ 73{
106 SLEntryPtr entry; 74 SLEntryPtr entry;
107 75
108 if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL; 76 if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL;
109 77
110 entry = SL_ALLOC(sizeof(*entry) 78 entry = drmMalloc(sizeof(*entry)
111 + (max_level + 1) * sizeof(entry->forward[0])); 79 + (max_level + 1) * sizeof(entry->forward[0]));
112 if (!entry) return NULL; 80 if (!entry) return NULL;
113 entry->magic = SL_ENTRY_MAGIC; 81 entry->magic = SL_ENTRY_MAGIC;
@@ -134,7 +102,7 @@ void *drmSLCreate(void)
134 SkipListPtr list; 102 SkipListPtr list;
135 int i; 103 int i;
136 104
137 list = SL_ALLOC(sizeof(*list)); 105 list = drmMalloc(sizeof(*list));
138 if (!list) return NULL; 106 if (!list) return NULL;
139 list->magic = SL_LIST_MAGIC; 107 list->magic = SL_LIST_MAGIC;
140 list->level = 0; 108 list->level = 0;
@@ -158,11 +126,11 @@ int drmSLDestroy(void *l)
158 if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */ 126 if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */
159 next = entry->forward[0]; 127 next = entry->forward[0];
160 entry->magic = SL_FREED_MAGIC; 128 entry->magic = SL_FREED_MAGIC;
161 SL_FREE(entry); 129 drmFree(entry);
162 } 130 }
163 131
164 list->magic = SL_FREED_MAGIC; 132 list->magic = SL_FREED_MAGIC;
165 SL_FREE(list); 133 drmFree(list);
166 return 0; 134 return 0;
167} 135}
168 136
@@ -236,7 +204,7 @@ int drmSLDelete(void *l, unsigned long key)
236 } 204 }
237 205
238 entry->magic = SL_FREED_MAGIC; 206 entry->magic = SL_FREED_MAGIC;
239 SL_FREE(entry); 207 drmFree(entry);
240 208
241 while (list->level && !list->head->forward[list->level]) --list->level; 209 while (list->level && !list->head->forward[list->level]) --list->level;
242 --list->count; 210 --list->count;
@@ -264,12 +232,14 @@ int drmSLLookupNeighbors(void *l, unsigned long key,
264 unsigned long *next_key, void **next_value) 232 unsigned long *next_key, void **next_value)
265{ 233{
266 SkipListPtr list = (SkipListPtr)l; 234 SkipListPtr list = (SkipListPtr)l;
267 SLEntryPtr update[SL_MAX_LEVEL + 1]; 235 SLEntryPtr update[SL_MAX_LEVEL + 1] = {0};
268 int retcode = 0; 236 int retcode = 0;
269 237
238 SLLocate(list, key, update);
239
270 *prev_key = *next_key = key; 240 *prev_key = *next_key = key;
271 *prev_value = *next_value = NULL; 241 *prev_value = *next_value = NULL;
272 242
273 if (update[0]) { 243 if (update[0]) {
274 *prev_key = update[0]->key; 244 *prev_key = update[0]->key;
275 *prev_value = update[0]->value; 245 *prev_value = update[0]->value;
@@ -346,132 +316,3 @@ void drmSLDump(void *l)
346 } 316 }
347 } 317 }
348} 318}
349
350#if SL_MAIN
351static void print(SkipListPtr list)
352{
353 unsigned long key;
354 void *value;
355
356 if (drmSLFirst(list, &key, &value)) {
357 do {
358 printf("key = %5lu, value = %p\n", key, value);
359 } while (drmSLNext(list, &key, &value));
360 }
361}
362
363static double do_time(int size, int iter)
364{
365 SkipListPtr list;
366 int i, j;
367 unsigned long keys[1000000];
368 unsigned long previous;
369 unsigned long key;
370 void *value;
371 struct timeval start, stop;
372 double usec;
373 SL_RANDOM_DECL;
374
375 SL_RANDOM_INIT(12345);
376
377 list = drmSLCreate();
378
379 for (i = 0; i < size; i++) {
380 keys[i] = SL_RANDOM;
381 drmSLInsert(list, keys[i], NULL);
382 }
383
384 previous = 0;
385 if (drmSLFirst(list, &key, &value)) {
386 do {
387 if (key <= previous) {
388 printf( "%lu !< %lu\n", previous, key);
389 }
390 previous = key;
391 } while (drmSLNext(list, &key, &value));
392 }
393
394 gettimeofday(&start, NULL);
395 for (j = 0; j < iter; j++) {
396 for (i = 0; i < size; i++) {
397 if (drmSLLookup(list, keys[i], &value))
398 printf("Error %lu %d\n", keys[i], i);
399 }
400 }
401 gettimeofday(&stop, NULL);
402
403 usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
404 - start.tv_sec * 1000000 - start.tv_usec) / (size * iter);
405
406 printf("%0.2f microseconds for list length %d\n", usec, size);
407
408 drmSLDestroy(list);
409
410 return usec;
411}
412
413static void print_neighbors(void *list, unsigned long key)
414{
415 unsigned long prev_key = 0;
416 unsigned long next_key = 0;
417 void *prev_value;
418 void *next_value;
419 int retval;
420
421 retval = drmSLLookupNeighbors(list, key,
422 &prev_key, &prev_value,
423 &next_key, &next_value);
424 printf("Neighbors of %5lu: %d %5lu %5lu\n",
425 key, retval, prev_key, next_key);
426}
427
428int main(void)
429{
430 SkipListPtr list;
431 double usec, usec2, usec3, usec4;
432
433 list = drmSLCreate();
434 printf( "list at %p\n", list);
435
436 print(list);
437 printf("\n==============================\n\n");
438
439 drmSLInsert(list, 123, NULL);
440 drmSLInsert(list, 213, NULL);
441 drmSLInsert(list, 50, NULL);
442 print(list);
443 printf("\n==============================\n\n");
444
445 print_neighbors(list, 0);
446 print_neighbors(list, 50);
447 print_neighbors(list, 51);
448 print_neighbors(list, 123);
449 print_neighbors(list, 200);
450 print_neighbors(list, 213);
451 print_neighbors(list, 256);
452 printf("\n==============================\n\n");
453
454 drmSLDelete(list, 50);
455 print(list);
456 printf("\n==============================\n\n");
457
458 drmSLDump(list);
459 drmSLDestroy(list);
460 printf("\n==============================\n\n");
461
462 usec = do_time(100, 10000);
463 usec2 = do_time(1000, 500);
464 printf("Table size increased by %0.2f, search time increased by %0.2f\n",
465 1000.0/100.0, usec2 / usec);
466
467 usec3 = do_time(10000, 50);
468 printf("Table size increased by %0.2f, search time increased by %0.2f\n",
469 10000.0/100.0, usec3 / usec);
470
471 usec4 = do_time(100000, 4);
472 printf("Table size increased by %0.2f, search time increased by %0.2f\n",
473 100000.0/100.0, usec4 / usec);
474
475 return 0;
476}
477#endif