diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..29b4f39 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,23 @@ +# To use this config with your editor, follow the instructions at: +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +insert_final_newline = true + +[*.{c,h}] +indent_style = space +indent_size = 4 + +[{Makefile.*,*.mk}] +indent_style = tab + +[*.m4] +indent_style = space +indent_size = 2 + +[{meson.build,meson_options.txt}] +indent_style = space +indent_size = 2 diff --git a/Android.common.mk b/Android.common.mk new file mode 100644 index 0000000..37c2b23 --- /dev/null +++ b/Android.common.mk @@ -0,0 +1,22 @@ +# XXX: Consider moving these to config.h analogous to autoconf. +LOCAL_CFLAGS += \ + -DMAJOR_IN_SYSMACROS=1 \ + -DHAVE_ALLOCA_H=0 \ + -DHAVE_SYS_SELECT_H=0 \ + -DHAVE_SYS_SYSCTL_H=0 \ + -DHAVE_VISIBILITY=1 \ + -fvisibility=hidden \ + -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 + +LOCAL_CFLAGS += \ + -Wno-error \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -Wno-pointer-arith \ + -Wno-enum-conversion + +# Quiet down the build system and remove any .h files from the sources +LOCAL_SRC_FILES := $(patsubst %.h, , $(LOCAL_SRC_FILES)) +LOCAL_EXPORT_C_INCLUDE_DIRS += $(LOCAL_PATH) + +LOCAL_PROPRIETARY_MODULE := true diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..0ab6f0f --- /dev/null +++ b/Android.mk @@ -0,0 +1,74 @@ +# +# Copyright © 2011-2012 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + +LIBDRM_ANDROID_MAJOR_VERSION := $(word 1, $(subst ., , $(PLATFORM_VERSION))) +ifneq ($(filter 2 4, $(LIBDRM_ANDROID_MAJOR_VERSION)),) +$(error "Android 4.4 and earlier not supported") +endif + +LIBDRM_COMMON_MK := $(call my-dir)/Android.common.mk + +LOCAL_PATH := $(call my-dir) +LIBDRM_TOP := $(LOCAL_PATH) + +include $(CLEAR_VARS) + +# Import variables LIBDRM_{,H,INCLUDE_H,INCLUDE_ANDROID_H,INCLUDE_VMWGFX_H}_FILES +include $(LOCAL_PATH)/Makefile.sources + +#static library for the device (recovery) +include $(CLEAR_VARS) +LOCAL_MODULE := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_FILES) +LOCAL_EXPORT_C_INCLUDE_DIRS := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/include/drm \ + $(LOCAL_PATH)/android + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include/drm + +include $(LIBDRM_COMMON_MK) +include $(BUILD_STATIC_LIBRARY) + +# Shared library for the device +include $(CLEAR_VARS) +LOCAL_MODULE := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_FILES) +LOCAL_EXPORT_C_INCLUDE_DIRS := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/include/drm \ + $(LOCAL_PATH)/android + +LOCAL_SHARED_LIBRARIES := \ + libcutils + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include/drm + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..96f1e4f --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,105 @@ +Contributing to libdrm +====================== + +Submitting Patches +------------------ + +Patches should be sent to dri-devel@lists.freedesktop.org, using git +send-email. For patches only touching driver specific code one of the driver +mailing lists (like amd-gfx@lists.freedesktop.org) is also appropriate. See git +documentation for help: + +http://git-scm.com/documentation + +Since dri-devel is a very busy mailing list please use --subject-prefix="PATCH +libdrm" to make it easier to find libdrm patches. This is best done by running + + git config --local format.subjectprefix "PATCH libdrm" + +The first line of a commit message should contain a prefix indicating what part +is affected by the patch followed by one sentence that describes the change. For +examples: + + amdgpu: Use uint32_t i in amdgpu_find_bo_by_cpu_mapping + +The body of the commit message should describe what the patch changes and why, +and also note any particular side effects. For a recommended reading on +writing commit messages, see: + +http://who-t.blogspot.de/2009/12/on-commit-messages.html + +Your patches should also include a Signed-off-by line with your name and email +address. If you're not the patch's original author, you should also gather +S-o-b's by them (and/or whomever gave the patch to you.) The significance of +this is that it certifies that you created the patch, that it was created under +an appropriate open source license, or provided to you under those terms. This +lets us indicate a chain of responsibility for the copyright status of the code. +For more details: + +https://developercertificate.org/ + +We won't reject patches that lack S-o-b, but it is strongly recommended. + +Review and Merging +------------------ + +Patches should have at least one positive review (Reviewed-by: tag) or +indication of approval (Acked-by: tag) before merging. For any code shared +between drivers this is mandatory. + +Please note that kernel/userspace API header files have special rules, see +include/drm/README. + +Coding style in the project loosely follows the CodingStyle of the linux kernel: + +https://www.kernel.org/doc/html/latest/process/coding-style.html?highlight=coding%20style + +Commit Rights +------------- + +Commit rights will be granted to anyone who requests them and fulfills the +below criteria: + +- Submitted a few (5-10 as a rule of thumb) non-trivial (not just simple + spelling fixes and whitespace adjustment) patches that have been merged + already. Since libdrm is just a glue library between the kernel and userspace + drivers, merged patches to those components also count towards the commit + criteria. + +- Are actively participating on discussions about their work (on the mailing + list or IRC). This should not be interpreted as a requirement to review other + peoples patches but just make sure that patch submission isn't one-way + communication. Cross-review is still highly encouraged. + +- Will be regularly contributing further patches. This includes regular + contributors to other parts of the open source graphics stack who only + do the oddball rare patch within libdrm itself. + +- Agrees to use their commit rights in accordance with the documented merge + criteria, tools, and processes. + +To apply for commit rights ("Developer" role in gitlab) send a mail to +dri-devel@lists.freedesktop.org and please ping the maintainers if your request +is stuck. + +Committers are encouraged to request their commit rights get removed when they +no longer contribute to the project. Commit rights will be reinstated when they +come back to the project. + +Maintainers and committers should encourage contributors to request commit +rights, as especially junior contributors tend to underestimate their skills. + +Code of Conduct +--------------- + +Please be aware the fd.o Code of Conduct also applies to libdrm: + +https://www.freedesktop.org/wiki/CodeOfConduct/ + +See the gitlab project owners for contact details of the libdrm maintainers. + +Abuse of commit rights, like engaging in commit fights or willfully pushing +patches that violate the documented merge criteria, will also be handled through +the Code of Conduct enforcement process. + +Happy hacking! diff --git a/CleanSpec.mk b/CleanSpec.mk new file mode 100644 index 0000000..28a11db --- /dev/null +++ b/CleanSpec.mk @@ -0,0 +1,4 @@ +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/libdrm) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/freedreno) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libdrm_*intermediates) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libdrm_*intermediates) diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..da995d0 --- /dev/null +++ b/README.rst @@ -0,0 +1,33 @@ +libdrm - userspace library for drm +---------------------------------- + +This is libdrm, a userspace library for accessing the DRM, direct rendering +manager, on Linux, BSD and other operating systems that support the ioctl +interface. +The library provides wrapper functions for the ioctls to avoid exposing the +kernel interface directly, and for chipsets with drm memory manager, support +for tracking relocations and buffers. +New functionality in the kernel DRM drivers typically requires a new libdrm, +but a new libdrm will always work with an older kernel. + +libdrm is a low-level library, typically used by graphics drivers such as +the Mesa drivers, the X drivers, libva and similar projects. + + +Compiling +--------- + +To set up meson: + + meson builddir/ + +By default this will install into /usr/local, you can change your prefix +with --prefix=/usr (or `meson configure builddir/ -Dprefix=/usr` after +the initial meson setup). + +Then use ninja to build and install: + + ninja -C builddir/ install + +If you are installing into a system location you will need to run install +separately, and as root. diff --git a/RELEASING b/RELEASING new file mode 100644 index 0000000..903c176 --- /dev/null +++ b/RELEASING @@ -0,0 +1,40 @@ +The release criteria for libdrm is essentially "if you need a release, +make one". There is no designated release engineer or maintainer. +Anybody is free to make a release if there's a certain feature or bug +fix they need in a released version of libdrm. + +When new ioctl definitions are merged into drm-next, we will add +support to libdrm, at which point we typically create a new release. +However, this is up to whoever is driving the feature in question. + +Follow these steps to release a new version of libdrm: + + 1) Bump the version number in meson.build. We seem to have settled for + 2.4.x as the versioning scheme for libdrm, so just bump the micro + version. + + 2) Run `ninja -C builddir/ dist` to generate the tarballs. + Make sure that the version number of the tarball name in + builddir/meson-dist/ matches the number you bumped to. Move that + tarball to the libdrm repo root for the release script to pick up. + + 3) Push the updated master branch with the bumped version number: + + git push origin master + + assuming the remote for the upstream libdrm repo is called origin. + + 4) Use the release.sh script from the xorg/util/modular repo to + upload the tarballs to the freedesktop.org download area and + create an announce email template. The script takes one argument: + the path to the libdrm checkout. So, if a checkout of modular is + at the same level than the libdrm repo: + + ./modular/release.sh libdrm + + This copies the two tarballs to freedesktop.org and creates + libdrm-2.4.16.announce which has a detailed summary of the + changes, links to the tarballs, MD5 and SHA1 sums and pre-filled + out email headers. Fill out the blank between the email headers + and the list of changes with a brief message of what changed or + what prompted this release. Send out the email and you're done! diff --git a/amdgpu/.editorconfig b/amdgpu/.editorconfig new file mode 100644 index 0000000..426273f --- /dev/null +++ b/amdgpu/.editorconfig @@ -0,0 +1,13 @@ +# To use this config with your editor, follow the instructions at: +# http://editorconfig.org + +[*] +charset = utf-8 +indent_style = tab +indent_size = 8 +tab_width = 8 +insert_final_newline = true + +[meson.build] +indent_style = space +indent_size = 2 diff --git a/amdgpu/Android.mk b/amdgpu/Android.mk new file mode 100644 index 0000000..1f028d0 --- /dev/null +++ b/amdgpu/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_AMDGPU_FILES, LIBDRM_AMDGPU_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_amdgpu + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_AMDGPU_FILES) + +LOCAL_CFLAGS := \ + -DAMDGPU_ASIC_ID_TABLE=\"/vendor/etc/hwdata/amdgpu.ids\" + +LOCAL_REQUIRED_MODULES := amdgpu.ids + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) diff --git a/amdgpu/amdgpu-symbols.txt b/amdgpu/amdgpu-symbols.txt new file mode 100644 index 0000000..e3bafaa --- /dev/null +++ b/amdgpu/amdgpu-symbols.txt @@ -0,0 +1,74 @@ +amdgpu_bo_alloc +amdgpu_bo_cpu_map +amdgpu_bo_cpu_unmap +amdgpu_bo_export +amdgpu_bo_free +amdgpu_bo_import +amdgpu_bo_inc_ref +amdgpu_bo_list_create_raw +amdgpu_bo_list_destroy_raw +amdgpu_bo_list_create +amdgpu_bo_list_destroy +amdgpu_bo_list_update +amdgpu_bo_query_info +amdgpu_bo_set_metadata +amdgpu_bo_va_op +amdgpu_bo_va_op_raw +amdgpu_bo_wait_for_idle +amdgpu_create_bo_from_user_mem +amdgpu_cs_chunk_fence_info_to_data +amdgpu_cs_chunk_fence_to_dep +amdgpu_cs_create_semaphore +amdgpu_cs_create_syncobj +amdgpu_cs_create_syncobj2 +amdgpu_cs_ctx_create +amdgpu_cs_ctx_create2 +amdgpu_cs_ctx_free +amdgpu_cs_ctx_override_priority +amdgpu_cs_destroy_semaphore +amdgpu_cs_destroy_syncobj +amdgpu_cs_export_syncobj +amdgpu_cs_fence_to_handle +amdgpu_cs_import_syncobj +amdgpu_cs_query_fence_status +amdgpu_cs_query_reset_state +amdgpu_cs_query_reset_state2 +amdgpu_query_sw_info +amdgpu_cs_signal_semaphore +amdgpu_cs_submit +amdgpu_cs_submit_raw +amdgpu_cs_submit_raw2 +amdgpu_cs_syncobj_export_sync_file +amdgpu_cs_syncobj_export_sync_file2 +amdgpu_cs_syncobj_import_sync_file +amdgpu_cs_syncobj_import_sync_file2 +amdgpu_cs_syncobj_query +amdgpu_cs_syncobj_query2 +amdgpu_cs_syncobj_reset +amdgpu_cs_syncobj_signal +amdgpu_cs_syncobj_timeline_signal +amdgpu_cs_syncobj_timeline_wait +amdgpu_cs_syncobj_transfer +amdgpu_cs_syncobj_wait +amdgpu_cs_wait_fences +amdgpu_cs_wait_semaphore +amdgpu_device_deinitialize +amdgpu_device_initialize +amdgpu_find_bo_by_cpu_mapping +amdgpu_get_marketing_name +amdgpu_query_buffer_size_alignment +amdgpu_query_crtc_from_id +amdgpu_query_firmware_version +amdgpu_query_gds_info +amdgpu_query_gpu_info +amdgpu_query_heap_info +amdgpu_query_hw_ip_count +amdgpu_query_hw_ip_info +amdgpu_query_info +amdgpu_query_sensor_info +amdgpu_read_mm_registers +amdgpu_va_range_alloc +amdgpu_va_range_free +amdgpu_va_range_query +amdgpu_vm_reserve_vmid +amdgpu_vm_unreserve_vmid diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h index bcac4cb..188179c 100644 --- a/amdgpu/amdgpu.h +++ b/amdgpu/amdgpu.h @@ -1606,6 +1606,24 @@ int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev, int amdgpu_cs_syncobj_query(amdgpu_device_handle dev, uint32_t *handles, uint64_t *points, unsigned num_handles); +/** + * Query sync objects last signaled or submitted point. + * + * \param dev - \c [in] self-explanatory + * \param handles - \c [in] array of sync object handles + * \param points - \c [out] array of sync points returned, which presents + * syncobj payload. + * \param num_handles - \c [in] self-explanatory + * \param flags - \c [in] a bitmask of DRM_SYNCOBJ_QUERY_FLAGS_* + * + * \return 0 on success\n + * -ETIME - Timeout + * <0 - Negative POSIX Error code + * + */ +int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev, + uint32_t *handles, uint64_t *points, + unsigned num_handles, uint32_t flags); /** * Export kernel sync object to shareable fd. diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c index 5650295..fad484b 100644 --- a/amdgpu/amdgpu_cs.c +++ b/amdgpu/amdgpu_cs.c @@ -28,7 +28,7 @@ #include #include #include -#ifdef HAVE_ALLOCA_H +#if HAVE_ALLOCA_H # include #endif @@ -220,15 +220,15 @@ drm_public int amdgpu_cs_query_reset_state2(amdgpu_context_handle context, static int amdgpu_cs_submit_one(amdgpu_context_handle context, struct amdgpu_cs_request *ibs_request) { - union drm_amdgpu_cs cs; - uint64_t *chunk_array; struct drm_amdgpu_cs_chunk *chunks; struct drm_amdgpu_cs_chunk_data *chunk_data; struct drm_amdgpu_cs_chunk_dep *dependencies = NULL; struct drm_amdgpu_cs_chunk_dep *sem_dependencies = NULL; + amdgpu_device_handle dev = context->dev; struct list_head *sem_list; amdgpu_semaphore_handle sem, tmp; - uint32_t i, size, sem_count = 0; + uint32_t i, size, num_chunks, bo_list_handle = 0, sem_count = 0; + uint64_t seq_no; bool user_fence; int r = 0; @@ -244,23 +244,18 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context, size = ibs_request->number_of_ibs + (user_fence ? 2 : 1) + 1; - chunk_array = alloca(sizeof(uint64_t) * size); chunks = alloca(sizeof(struct drm_amdgpu_cs_chunk) * size); size = ibs_request->number_of_ibs + (user_fence ? 1 : 0); chunk_data = alloca(sizeof(struct drm_amdgpu_cs_chunk_data) * size); - memset(&cs, 0, sizeof(cs)); - cs.in.chunks = (uint64_t)(uintptr_t)chunk_array; - cs.in.ctx_id = context->id; if (ibs_request->resources) - cs.in.bo_list_handle = ibs_request->resources->handle; - cs.in.num_chunks = ibs_request->number_of_ibs; + bo_list_handle = ibs_request->resources->handle; + num_chunks = ibs_request->number_of_ibs; /* IB chunks */ for (i = 0; i < ibs_request->number_of_ibs; i++) { struct amdgpu_cs_ib_info *ib; - chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i]; chunks[i].chunk_id = AMDGPU_CHUNK_ID_IB; chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4; chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i]; @@ -279,10 +274,9 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context, pthread_mutex_lock(&context->sequence_mutex); if (user_fence) { - i = cs.in.num_chunks++; + i = num_chunks++; /* fence chunk */ - chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i]; chunks[i].chunk_id = AMDGPU_CHUNK_ID_FENCE; chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_fence) / 4; chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i]; @@ -295,7 +289,7 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context, } if (ibs_request->number_of_dependencies) { - dependencies = malloc(sizeof(struct drm_amdgpu_cs_chunk_dep) * + dependencies = alloca(sizeof(struct drm_amdgpu_cs_chunk_dep) * ibs_request->number_of_dependencies); if (!dependencies) { r = -ENOMEM; @@ -312,10 +306,9 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context, dep->handle = info->fence; } - i = cs.in.num_chunks++; + i = num_chunks++; /* dependencies chunk */ - chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i]; chunks[i].chunk_id = AMDGPU_CHUNK_ID_DEPENDENCIES; chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_dep) / 4 * ibs_request->number_of_dependencies; @@ -326,7 +319,7 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context, LIST_FOR_EACH_ENTRY(sem, sem_list, list) sem_count++; if (sem_count) { - sem_dependencies = malloc(sizeof(struct drm_amdgpu_cs_chunk_dep) * sem_count); + sem_dependencies = alloca(sizeof(struct drm_amdgpu_cs_chunk_dep) * sem_count); if (!sem_dependencies) { r = -ENOMEM; goto error_unlock; @@ -345,26 +338,23 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context, amdgpu_cs_reset_sem(sem); amdgpu_cs_unreference_sem(sem); } - i = cs.in.num_chunks++; + i = num_chunks++; /* dependencies chunk */ - chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i]; chunks[i].chunk_id = AMDGPU_CHUNK_ID_DEPENDENCIES; chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_dep) / 4 * sem_count; chunks[i].chunk_data = (uint64_t)(uintptr_t)sem_dependencies; } - r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CS, - &cs, sizeof(cs)); + r = amdgpu_cs_submit_raw2(dev, context, bo_list_handle, num_chunks, + chunks, &seq_no); if (r) goto error_unlock; - ibs_request->seq_no = cs.out.handle; + ibs_request->seq_no = seq_no; context->last_seq[ibs_request->ip_type][ibs_request->ip_instance][ibs_request->ring] = ibs_request->seq_no; error_unlock: pthread_mutex_unlock(&context->sequence_mutex); - free(dependencies); - free(sem_dependencies); return r; } @@ -740,6 +730,16 @@ drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev, return drmSyncobjQuery(dev->fd, handles, points, num_handles); } +drm_public int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev, + uint32_t *handles, uint64_t *points, + unsigned num_handles, uint32_t flags) +{ + if (!dev) + return -EINVAL; + + return drmSyncobjQuery2(dev->fd, handles, points, num_handles, flags); +} + drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev, uint32_t handle, int *shared_fd) diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h index a340abb..37a7c9d 100644 --- a/amdgpu/amdgpu_internal.h +++ b/amdgpu/amdgpu_internal.h @@ -102,7 +102,7 @@ struct amdgpu_bo { pthread_mutex_t cpu_access_mutex; void *cpu_ptr; - int cpu_map_count; + int64_t cpu_map_count; }; struct amdgpu_bo_list { diff --git a/amdgpu/meson.build b/amdgpu/meson.build index 8168993..a1781f5 100644 --- a/amdgpu/meson.build +++ b/amdgpu/meson.build @@ -58,8 +58,11 @@ ext_libdrm_amdgpu = declare_dependency( ) test( - 'amdgpu-symbol-check', - find_program('amdgpu-symbol-check'), - env : env_test, - args : libdrm_amdgpu, + 'amdgpu-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_amdgpu, + '--symbols-file', files('amdgpu-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/android/gralloc_handle.h b/android/gralloc_handle.h new file mode 100644 index 0000000..d3d975e --- /dev/null +++ b/android/gralloc_handle.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2010-2011 Chia-I Wu + * Copyright (C) 2010-2011 LunarG Inc. + * Copyright (C) 2016 Linaro, Ltd., Rob Herring + * Copyright (C) 2018 Collabora, Robert Foss + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __ANDROID_GRALLOC_HANDLE_H__ +#define __ANDROID_GRALLOC_HANDLE_H__ + +#include +#include + +/* support users of drm_gralloc/gbm_gralloc */ +#define gralloc_gbm_handle_t gralloc_handle_t +#define gralloc_drm_handle_t gralloc_handle_t + +struct gralloc_handle_t { + native_handle_t base; + + /* dma-buf file descriptor + * Must be located first since, native_handle_t is allocated + * using native_handle_create(), which allocates space for + * sizeof(native_handle_t) + sizeof(int) * (numFds + numInts) + * numFds = GRALLOC_HANDLE_NUM_FDS + * numInts = GRALLOC_HANDLE_NUM_INTS + * Where numFds represents the number of FDs and + * numInts represents the space needed for the + * remainder of this struct. + * And the FDs are expected to be found first following + * native_handle_t. + */ + int prime_fd; + + /* api variables */ + uint32_t magic; /* differentiate between allocator impls */ + uint32_t version; /* api version */ + + uint32_t width; /* width of buffer in pixels */ + uint32_t height; /* height of buffer in pixels */ + uint32_t format; /* pixel format (Android) */ + uint32_t usage; /* android libhardware usage flags */ + + uint32_t stride; /* the stride in bytes */ + int data_owner; /* owner of data (for validation) */ + uint64_t modifier __attribute__((aligned(8))); /* buffer modifiers */ + + union { + void *data; /* pointer to struct gralloc_gbm_bo_t */ + uint64_t reserved; + } __attribute__((aligned(8))); +}; + +#define GRALLOC_HANDLE_VERSION 4 +#define GRALLOC_HANDLE_MAGIC 0x60585350 +#define GRALLOC_HANDLE_NUM_FDS 1 +#define GRALLOC_HANDLE_NUM_INTS ( \ + ((sizeof(struct gralloc_handle_t) - sizeof(native_handle_t))/sizeof(int)) \ + - GRALLOC_HANDLE_NUM_FDS) + +static inline struct gralloc_handle_t *gralloc_handle(buffer_handle_t handle) +{ + return (struct gralloc_handle_t *)handle; +} + +/** + * Create a buffer handle. + */ +static inline native_handle_t *gralloc_handle_create(int32_t width, + int32_t height, + int32_t hal_format, + int32_t usage) +{ + struct gralloc_handle_t *handle; + native_handle_t *nhandle = native_handle_create(GRALLOC_HANDLE_NUM_FDS, + GRALLOC_HANDLE_NUM_INTS); + + if (!nhandle) + return NULL; + + handle = gralloc_handle(nhandle); + handle->magic = GRALLOC_HANDLE_MAGIC; + handle->version = GRALLOC_HANDLE_VERSION; + handle->width = width; + handle->height = height; + handle->format = hal_format; + handle->usage = usage; + handle->prime_fd = -1; + + return nhandle; +} + +#endif diff --git a/core-symbols.txt b/core-symbols.txt new file mode 100644 index 0000000..1ff4eca --- /dev/null +++ b/core-symbols.txt @@ -0,0 +1,197 @@ +drmAddBufs +drmAddContextPrivateMapping +drmAddContextTag +drmAddMap +drmAgpAcquire +drmAgpAlloc +drmAgpBase +drmAgpBind +drmAgpDeviceId +drmAgpEnable +drmAgpFree +drmAgpGetMode +drmAgpMemoryAvail +drmAgpMemoryUsed +drmAgpRelease +drmAgpSize +drmAgpUnbind +drmAgpVendorId +drmAgpVersionMajor +drmAgpVersionMinor +drmAuthMagic +drmAvailable +drmCheckModesettingSupported +drmClose +drmCloseOnce +drmCommandNone +drmCommandRead +drmCommandWrite +drmCommandWriteRead +drmCreateContext +drmCreateDrawable +drmCrtcGetSequence +drmCrtcQueueSequence +drmCtlInstHandler +drmCtlUninstHandler +drmDelContextTag +drmDestroyContext +drmDestroyDrawable +drmDevicesEqual +drmDMA +drmDropMaster +drmError +drmFinish +drmFree +drmFreeBufs +drmFreeBusid +drmFreeDevice +drmFreeDevices +drmFreeReservedContextList +drmFreeVersion +drmGetBufInfo +drmGetBusid +drmGetCap +drmGetClient +drmGetContextFlags +drmGetContextPrivateMapping +drmGetContextTag +drmGetDevice +drmGetDevice2 +drmGetDeviceNameFromFd +drmGetDeviceNameFromFd2 +drmGetDevices +drmGetDevices2 +drmGetEntry +drmGetHashTable +drmGetInterruptFromBusID +drmGetLibVersion +drmGetLock +drmGetMagic +drmGetMap +drmGetNodeTypeFromFd +drmGetPrimaryDeviceNameFromFd +drmGetRenderDeviceNameFromFd +drmGetReservedContextList +drmGetStats +drmGetVersion +drmHandleEvent +drmHashCreate +drmHashDelete +drmHashDestroy +drmHashFirst +drmHashInsert +drmHashLookup +drmHashNext +drmIoctl +drmIsMaster +drmMalloc +drmMap +drmMapBufs +drmMarkBufs +drmModeAddFB +drmModeAddFB2 +drmModeAddFB2WithModifiers +drmModeAtomicAddProperty +drmModeAtomicAlloc +drmModeAtomicCommit +drmModeAtomicDuplicate +drmModeAtomicFree +drmModeAtomicGetCursor +drmModeAtomicMerge +drmModeAtomicSetCursor +drmModeAttachMode +drmModeConnectorSetProperty +drmModeCreateLease +drmModeCreatePropertyBlob +drmModeCrtcGetGamma +drmModeCrtcSetGamma +drmModeDestroyPropertyBlob +drmModeDetachMode +drmModeDirtyFB +drmModeFreeConnector +drmModeFreeCrtc +drmModeFreeEncoder +drmModeFreeFB +drmModeFreeFB2 +drmModeFreeModeInfo +drmModeFreeObjectProperties +drmModeFreePlane +drmModeFreePlaneResources +drmModeFreeProperty +drmModeFreePropertyBlob +drmModeFreeResources +drmModeGetConnector +drmModeGetConnectorCurrent +drmModeGetCrtc +drmModeGetEncoder +drmModeGetFB +drmModeGetFB2 +drmModeGetLease +drmModeGetPlane +drmModeGetPlaneResources +drmModeGetProperty +drmModeGetPropertyBlob +drmModeGetResources +drmModeListLessees +drmModeMoveCursor +drmModeObjectGetProperties +drmModeObjectSetProperty +drmModePageFlip +drmModePageFlipTarget +drmModeRevokeLease +drmModeRmFB +drmModeSetCrtc +drmModeSetCursor +drmModeSetCursor2 +drmModeSetPlane +drmMsg +drmOpen +drmOpenControl +drmOpenOnce +drmOpenOnceWithType +drmOpenRender +drmOpenWithType +drmPrimeFDToHandle +drmPrimeHandleToFD +drmRandom +drmRandomCreate +drmRandomDestroy +drmRandomDouble +drmRmMap +drmScatterGatherAlloc +drmScatterGatherFree +drmSetBusid +drmSetClientCap +drmSetContextFlags +drmSetInterfaceVersion +drmSetMaster +drmSetServerInfo +drmSLCreate +drmSLDelete +drmSLDestroy +drmSLDump +drmSLFirst +drmSLInsert +drmSLLookup +drmSLLookupNeighbors +drmSLNext +drmSwitchToContext +drmSyncobjCreate +drmSyncobjDestroy +drmSyncobjExportSyncFile +drmSyncobjFDToHandle +drmSyncobjHandleToFD +drmSyncobjImportSyncFile +drmSyncobjQuery +drmSyncobjQuery2 +drmSyncobjReset +drmSyncobjSignal +drmSyncobjTimelineSignal +drmSyncobjTimelineWait +drmSyncobjTransfer +drmSyncobjWait +drmUnlock +drmUnmap +drmUnmapBufs +drmUpdateDrawableInfo +drmWaitVBlank diff --git a/data/Android.mk b/data/Android.mk new file mode 100644 index 0000000..62013f0 --- /dev/null +++ b/data/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := amdgpu.ids +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := ETC +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := hwdata +LOCAL_SRC_FILES := $(LOCAL_MODULE) +include $(BUILD_PREBUILT) diff --git a/data/amdgpu.ids b/data/amdgpu.ids index f61497e..6fc6858 100644 --- a/data/amdgpu.ids +++ b/data/amdgpu.ids @@ -140,6 +140,7 @@ 6860, 02, Radeon Instinct MI25 6860, 03, Radeon Pro V340 6860, 04, Radeon Instinct MI25x2 +6860, 07, Radeon (TM) Pro V320 6861, 00, Radeon Pro WX 9100 6862, 00, Radeon Pro SSG 6863, 00, Radeon Vega Frontier Edition @@ -174,6 +175,9 @@ 6939, 0, AMD Radeon R9 200 Series 6939, F1, AMD Radeon (TM) R9 380 Series 6980, 00, Radeon Pro WX3100 +6981, 00, AMD Radeon (TM) Pro WX 3200 Series +6981, 01, AMD Radeon (TM) Pro WX 3200 Series +6981, 10, AMD Radeon (TM) Pro WX 3200 Series 6985, 00, AMD Radeon Pro WX3100 6987, 80, AMD Embedded Radeon E9171 6987, C0, Radeon 550X Series @@ -184,12 +188,26 @@ 699F, C0, Radeon 500 Series 699F, C1, Radeon 540 Series 699F, C3, Radeon 500 Series -699F, C7, Radeon 550 Series +699F, C7, Radeon RX550/550 Series 7300, C1, AMD FirePro (TM) S9300 x2 7300, C8, AMD Radeon (TM) R9 Fury Series 7300, C9, Radeon (TM) Pro Duo 7300, CB, AMD Radeon (TM) R9 Fury Series 7300, CA, AMD Radeon (TM) R9 Fury Series +7312, 00, AMD Radeon Pro W5700 +731F, C0, AMD Radeon RX 5700 XT 50th Anniversary +731F, C1, AMD Radeon RX 5700 XT +731F, C2, AMD Radeon RX 5600M +731F, C3, AMD Radeon RX 5700M +731F, C4, AMD Radeon RX 5700 +731F, C5, AMD Radeon RX 5700 XT +731F, CA, AMD Radeon RX 5600 XT +731F, CB, AMD Radeon RX 5600 OEM +7340, C1, Radeon RX 5500M +7340, C5, Radeon RX 5500 XT +7340, C7, Radeon RX 5500 +7341, 00, AMD Radeon Pro W5500 +7347, 00, AMD Radeon Pro W5500M 9874, C4, AMD Radeon R7 Graphics 9874, C5, AMD Radeon R6 Graphics 9874, C6, AMD Radeon R6 Graphics diff --git a/etnaviv/Android.mk b/etnaviv/Android.mk new file mode 100644 index 0000000..390f9a9 --- /dev/null +++ b/etnaviv/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_ETNAVIV_FILES, LIBDRM_ETNAVIV_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_etnaviv + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_ETNAVIV_FILES) + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) diff --git a/etnaviv/etnaviv-symbols.txt b/etnaviv/etnaviv-symbols.txt new file mode 100644 index 0000000..f48cece --- /dev/null +++ b/etnaviv/etnaviv-symbols.txt @@ -0,0 +1,36 @@ +etna_device_new +etna_device_new_dup +etna_device_ref +etna_device_del +etna_device_fd +etna_gpu_new +etna_gpu_del +etna_gpu_get_param +etna_pipe_new +etna_pipe_del +etna_pipe_wait +etna_pipe_wait_ns +etna_bo_new +etna_bo_from_name +etna_bo_from_dmabuf +etna_bo_ref +etna_bo_del +etna_bo_get_name +etna_bo_handle +etna_bo_dmabuf +etna_bo_size +etna_bo_map +etna_bo_cpu_prep +etna_bo_cpu_fini +etna_cmd_stream_new +etna_cmd_stream_del +etna_cmd_stream_timestamp +etna_cmd_stream_flush +etna_cmd_stream_flush2 +etna_cmd_stream_finish +etna_cmd_stream_perf +etna_cmd_stream_reloc +etna_perfmon_create +etna_perfmon_del +etna_perfmon_get_dom_by_name +etna_perfmon_get_sig_by_name diff --git a/etnaviv/meson.build b/etnaviv/meson.build index 1ecf294..6040cf6 100644 --- a/etnaviv/meson.build +++ b/etnaviv/meson.build @@ -53,8 +53,11 @@ ext_libdrm_etnaviv = declare_dependency( ) test( - 'etnaviv-symbol-check', - find_program('etnaviv-symbol-check'), - env : env_test, - args : libdrm_etnaviv, + 'etnaviv-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_etnaviv, + '--symbols-file', files('etnaviv-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/exynos/exynos-symbols.txt b/exynos/exynos-symbols.txt new file mode 100644 index 0000000..c674841 --- /dev/null +++ b/exynos/exynos-symbols.txt @@ -0,0 +1,23 @@ +exynos_bo_create +exynos_bo_destroy +exynos_bo_from_name +exynos_bo_get_info +exynos_bo_get_name +exynos_bo_handle +exynos_bo_map +exynos_device_create +exynos_device_destroy +exynos_prime_fd_to_handle +exynos_prime_handle_to_fd +exynos_vidi_connection +exynos_handle_event +g2d_blend +g2d_copy +g2d_copy_with_scale +g2d_exec +g2d_config_event +g2d_fini +g2d_init +g2d_move +g2d_scale_and_blend +g2d_solid_fill diff --git a/exynos/meson.build b/exynos/meson.build index 0136cb2..40d66fc 100644 --- a/exynos/meson.build +++ b/exynos/meson.build @@ -47,8 +47,11 @@ pkg.generate( ) test( - 'exynos-symbol-check', - find_program('exynos-symbol-check'), - env : env_test, - args : libdrm_exynos, + 'exynos-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_exynos, + '--symbols-file', files('exynos-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/freedreno/Android.mk b/freedreno/Android.mk new file mode 100644 index 0000000..2b582ae --- /dev/null +++ b/freedreno/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_FREEDRENO_FILES, LIBDRM_FREEDRENO_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_freedreno + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_FREEDRENO_FILES) + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) diff --git a/freedreno/freedreno-symbols.txt b/freedreno/freedreno-symbols.txt new file mode 100644 index 0000000..471ca99 --- /dev/null +++ b/freedreno/freedreno-symbols.txt @@ -0,0 +1,45 @@ +fd_bo_cpu_fini +fd_bo_cpu_prep +fd_bo_del +fd_bo_dmabuf +fd_bo_from_dmabuf +fd_bo_from_fbdev +fd_bo_from_handle +fd_bo_from_name +fd_bo_get_iova +fd_bo_get_name +fd_bo_handle +fd_bo_map +fd_bo_new +fd_bo_put_iova +fd_bo_ref +fd_bo_size +fd_device_del +fd_device_fd +fd_device_new +fd_device_new_dup +fd_device_ref +fd_device_version +fd_pipe_del +fd_pipe_get_param +fd_pipe_new +fd_pipe_new2 +fd_pipe_ref +fd_pipe_wait +fd_pipe_wait_timeout +fd_ringbuffer_cmd_count +fd_ringbuffer_del +fd_ringbuffer_emit_reloc_ring_full +fd_ringbuffer_flush +fd_ringbuffer_grow +fd_ringbuffer_new +fd_ringbuffer_new_flags +fd_ringbuffer_new_object +fd_ringbuffer_ref +fd_ringbuffer_reloc +fd_ringbuffer_reloc2 +fd_ringbuffer_reset +fd_ringbuffer_set_parent +fd_ringbuffer_size +fd_ringbuffer_timestamp +fd_ringbuffer_flush2 diff --git a/freedreno/kgsl/README b/freedreno/kgsl/README new file mode 100644 index 0000000..c46ba08 --- /dev/null +++ b/freedreno/kgsl/README @@ -0,0 +1,26 @@ +This is a historical description of what is now the kgsl backend +in libdrm freedreno (before the upstream drm/msm driver). Note +that the kgsl backend requires the "kgsl-drm" shim driver, which +usually is in disrepair (QCOM does not build it for android), and +due to random differences between different downstream android +kernel branches it may or may not work. So YMMV. + +Original README: +---------------- + +Note that current msm kernel driver is a bit strange. It provides a +DRM interface for GEM, which is basically sufficient to have DRI2 +working. But it does not provide KMS. And interface to 2d and 3d +cores is via different other devices (/dev/kgsl-*). This is not +quite how I'd write a DRM driver, but at this stage it is useful for +xf86-video-freedreno and fdre (and eventual gallium driver) to be +able to work on existing kernel driver from QCOM, to allow to +capture cmdstream dumps from the binary blob drivers without having +to reboot. So libdrm_freedreno attempts to hide most of the crazy. +The intention is that when there is a proper kernel driver, it will +be mostly just changes in libdrm_freedreno to adapt the gallium +driver and xf86-video-freedreno (ignoring the fbdev->KMS changes). + +So don't look at freedreno as an example of how to write a libdrm +module or a DRM driver.. it is just an attempt to paper over a non- +standard kernel driver architecture. diff --git a/freedreno/meson.build b/freedreno/meson.build index 5d8d8e9..63b84fc 100644 --- a/freedreno/meson.build +++ b/freedreno/meson.build @@ -70,8 +70,11 @@ pkg.generate( ) test( - 'freedreno-symbol-check', - find_program('freedreno-symbol-check'), - env : env_test, - args : libdrm_freedreno, + 'freedreno-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_freedreno, + '--symbols-file', files('freedreno-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/include/drm/drm.h b/include/drm/drm.h index 438abde..c7fd2a3 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -772,11 +772,12 @@ struct drm_syncobj_array { __u32 pad; }; +#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available point on timeline syncobj */ struct drm_syncobj_timeline_array { __u64 handles; __u64 points; __u32 count_handles; - __u32 pad; + __u32 flags; }; @@ -941,6 +942,8 @@ extern "C" { #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array) +#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2) + /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. diff --git a/intel/.gitignore b/intel/.gitignore new file mode 100644 index 0000000..528b408 --- /dev/null +++ b/intel/.gitignore @@ -0,0 +1 @@ +test_decode diff --git a/intel/Android.mk b/intel/Android.mk new file mode 100644 index 0000000..f45312d --- /dev/null +++ b/intel/Android.mk @@ -0,0 +1,38 @@ +# +# Copyright © 2011 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_INTEL_FILES, LIBDRM_INTEL_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_intel + +LOCAL_SRC_FILES := $(LIBDRM_INTEL_FILES) + +LOCAL_SHARED_LIBRARIES := \ + libdrm + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) diff --git a/intel/i915_pciids.h b/intel/i915_pciids.h index b1f66b1..662d835 100644 --- a/intel/i915_pciids.h +++ b/intel/i915_pciids.h @@ -446,23 +446,18 @@ /* CML GT1 */ #define INTEL_CML_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x9B21, info), \ - INTEL_VGA_DEVICE(0x9BAA, info), \ - INTEL_VGA_DEVICE(0x9BAB, info), \ - INTEL_VGA_DEVICE(0x9BAC, info), \ - INTEL_VGA_DEVICE(0x9BA0, info), \ INTEL_VGA_DEVICE(0x9BA5, info), \ INTEL_VGA_DEVICE(0x9BA8, info), \ INTEL_VGA_DEVICE(0x9BA4, info), \ INTEL_VGA_DEVICE(0x9BA2, info) +#define INTEL_CML_U_GT1_IDS(info) \ + INTEL_VGA_DEVICE(0x9B21, info), \ + INTEL_VGA_DEVICE(0x9BAA, info), \ + INTEL_VGA_DEVICE(0x9BAC, info) + /* CML GT2 */ #define INTEL_CML_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x9B41, info), \ - INTEL_VGA_DEVICE(0x9BCA, info), \ - INTEL_VGA_DEVICE(0x9BCB, info), \ - INTEL_VGA_DEVICE(0x9BCC, info), \ - INTEL_VGA_DEVICE(0x9BC0, info), \ INTEL_VGA_DEVICE(0x9BC5, info), \ INTEL_VGA_DEVICE(0x9BC8, info), \ INTEL_VGA_DEVICE(0x9BC4, info), \ @@ -471,6 +466,11 @@ INTEL_VGA_DEVICE(0x9BE6, info), \ INTEL_VGA_DEVICE(0x9BF6, info) +#define INTEL_CML_U_GT2_IDS(info) \ + INTEL_VGA_DEVICE(0x9B41, info), \ + INTEL_VGA_DEVICE(0x9BCA, info), \ + INTEL_VGA_DEVICE(0x9BCC, info) + #define INTEL_KBL_IDS(info) \ INTEL_KBL_GT1_IDS(info), \ INTEL_KBL_GT2_IDS(info), \ @@ -536,7 +536,9 @@ INTEL_WHL_U_GT3_IDS(info), \ INTEL_AML_CFL_GT2_IDS(info), \ INTEL_CML_GT1_IDS(info), \ - INTEL_CML_GT2_IDS(info) + INTEL_CML_GT2_IDS(info), \ + INTEL_CML_U_GT1_IDS(info), \ + INTEL_CML_U_GT2_IDS(info) /* CNL */ #define INTEL_CNL_PORT_F_IDS(info) \ @@ -579,21 +581,28 @@ INTEL_VGA_DEVICE(0x8A51, info), \ INTEL_VGA_DEVICE(0x8A5D, info) -/* EHL */ +/* EHL/JSL */ #define INTEL_EHL_IDS(info) \ INTEL_VGA_DEVICE(0x4500, info), \ INTEL_VGA_DEVICE(0x4571, info), \ INTEL_VGA_DEVICE(0x4551, info), \ - INTEL_VGA_DEVICE(0x4541, info) + INTEL_VGA_DEVICE(0x4541, info), \ + INTEL_VGA_DEVICE(0x4E71, info), \ + INTEL_VGA_DEVICE(0x4E61, info), \ + INTEL_VGA_DEVICE(0x4E51, info) /* TGL */ #define INTEL_TGL_12_IDS(info) \ - INTEL_VGA_DEVICE(0x9A49, info), \ INTEL_VGA_DEVICE(0x9A40, info), \ + INTEL_VGA_DEVICE(0x9A49, info), \ INTEL_VGA_DEVICE(0x9A59, info), \ INTEL_VGA_DEVICE(0x9A60, info), \ INTEL_VGA_DEVICE(0x9A68, info), \ INTEL_VGA_DEVICE(0x9A70, info), \ - INTEL_VGA_DEVICE(0x9A78, info) + INTEL_VGA_DEVICE(0x9A78, info), \ + INTEL_VGA_DEVICE(0x9AC0, info), \ + INTEL_VGA_DEVICE(0x9AC9, info), \ + INTEL_VGA_DEVICE(0x9AD9, info), \ + INTEL_VGA_DEVICE(0x9AF8, info) #endif /* _I915_PCIIDS_H */ diff --git a/intel/intel-symbols.txt b/intel/intel-symbols.txt new file mode 100644 index 0000000..132df96 --- /dev/null +++ b/intel/intel-symbols.txt @@ -0,0 +1,83 @@ +drm_intel_bo_alloc +drm_intel_bo_alloc_for_render +drm_intel_bo_alloc_tiled +drm_intel_bo_alloc_userptr +drm_intel_bo_busy +drm_intel_bo_disable_reuse +drm_intel_bo_emit_reloc +drm_intel_bo_emit_reloc_fence +drm_intel_bo_exec +drm_intel_bo_fake_alloc_static +drm_intel_bo_fake_disable_backing_store +drm_intel_bo_flink +drm_intel_bo_gem_create_from_name +drm_intel_bo_gem_create_from_prime +drm_intel_bo_gem_export_to_prime +drm_intel_bo_get_subdata +drm_intel_bo_get_tiling +drm_intel_bo_is_reusable +drm_intel_bo_madvise +drm_intel_bo_map +drm_intel_bo_mrb_exec +drm_intel_bo_pin +drm_intel_bo_reference +drm_intel_bo_references +drm_intel_bo_set_softpin_offset +drm_intel_bo_set_tiling +drm_intel_bo_subdata +drm_intel_bo_unmap +drm_intel_bo_unpin +drm_intel_bo_unreference +drm_intel_bo_use_48b_address_range +drm_intel_bo_wait_rendering +drm_intel_bufmgr_check_aperture_space +drm_intel_bufmgr_destroy +drm_intel_bufmgr_fake_contended_lock_take +drm_intel_bufmgr_fake_evict_all +drm_intel_bufmgr_fake_init +drm_intel_bufmgr_fake_set_exec_callback +drm_intel_bufmgr_fake_set_fence_callback +drm_intel_bufmgr_fake_set_last_dispatch +drm_intel_bufmgr_gem_can_disable_implicit_sync +drm_intel_bufmgr_gem_enable_fenced_relocs +drm_intel_bufmgr_gem_enable_reuse +drm_intel_bufmgr_gem_get_devid +drm_intel_bufmgr_gem_init +drm_intel_bufmgr_gem_set_aub_annotations +drm_intel_bufmgr_gem_set_aub_dump +drm_intel_bufmgr_gem_set_aub_filename +drm_intel_bufmgr_gem_set_vma_cache_size +drm_intel_bufmgr_set_debug +drm_intel_decode +drm_intel_decode_context_alloc +drm_intel_decode_context_free +drm_intel_decode_set_batch_pointer +drm_intel_decode_set_dump_past_end +drm_intel_decode_set_head_tail +drm_intel_decode_set_output_file +drm_intel_gem_bo_aub_dump_bmp +drm_intel_gem_bo_clear_relocs +drm_intel_gem_bo_context_exec +drm_intel_gem_bo_disable_implicit_sync +drm_intel_gem_bo_enable_implicit_sync +drm_intel_gem_bo_fence_exec +drm_intel_gem_bo_get_reloc_count +drm_intel_gem_bo_map__cpu +drm_intel_gem_bo_map__gtt +drm_intel_gem_bo_map__wc +drm_intel_gem_bo_map_gtt +drm_intel_gem_bo_map_unsynchronized +drm_intel_gem_bo_start_gtt_access +drm_intel_gem_bo_unmap_gtt +drm_intel_gem_bo_wait +drm_intel_gem_context_create +drm_intel_gem_context_destroy +drm_intel_gem_context_get_id +drm_intel_get_aperture_sizes +drm_intel_get_eu_total +drm_intel_get_min_eu_in_pool +drm_intel_get_pipe_from_crtc_id +drm_intel_get_pooled_eu +drm_intel_get_reset_stats +drm_intel_get_subslice_total +drm_intel_reg_read diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index fbf4873..ade13a4 100644 --- a/intel/intel_bufmgr_gem.c +++ b/intel/intel_bufmgr_gem.c @@ -1069,6 +1069,28 @@ check_bo_alloc_userptr(drm_intel_bufmgr *bufmgr, tiling_mode, stride, size, flags); } +static int get_tiling_mode(drm_intel_bufmgr_gem *bufmgr_gem, + uint32_t gem_handle, + uint32_t *tiling_mode, + uint32_t *swizzle_mode) +{ + struct drm_i915_gem_get_tiling get_tiling = { + .handle = gem_handle, + }; + int ret; + + ret = drmIoctl(bufmgr_gem->fd, + DRM_IOCTL_I915_GEM_GET_TILING, + &get_tiling); + if (ret != 0 && errno != EOPNOTSUPP) + return ret; + + *tiling_mode = get_tiling.tiling_mode; + *swizzle_mode = get_tiling.swizzle_mode; + + return 0; +} + /** * Returns a drm_intel_bo wrapping the given buffer object handle. * @@ -1084,7 +1106,6 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr, drm_intel_bo_gem *bo_gem; int ret; struct drm_gem_open open_arg; - struct drm_i915_gem_get_tiling get_tiling; /* At the moment most applications only have a few named bo. * For instance, in a DRI client only the render buffers passed @@ -1146,16 +1167,11 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr, HASH_ADD(name_hh, bufmgr_gem->name_table, global_name, sizeof(bo_gem->global_name), bo_gem); - memclear(get_tiling); - get_tiling.handle = bo_gem->gem_handle; - ret = drmIoctl(bufmgr_gem->fd, - DRM_IOCTL_I915_GEM_GET_TILING, - &get_tiling); + ret = get_tiling_mode(bufmgr_gem, bo_gem->gem_handle, + &bo_gem->tiling_mode, &bo_gem->swizzle_mode); if (ret != 0) goto err_unref; - bo_gem->tiling_mode = get_tiling.tiling_mode; - bo_gem->swizzle_mode = get_tiling.swizzle_mode; /* XXX stride is unknown */ drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0); DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name); @@ -2634,7 +2650,6 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s int ret; uint32_t handle; drm_intel_bo_gem *bo_gem; - struct drm_i915_gem_get_tiling get_tiling; pthread_mutex_lock(&bufmgr_gem->lock); ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle); @@ -2688,15 +2703,11 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s bo_gem->has_error = false; bo_gem->reusable = false; - memclear(get_tiling); - get_tiling.handle = bo_gem->gem_handle; - if (drmIoctl(bufmgr_gem->fd, - DRM_IOCTL_I915_GEM_GET_TILING, - &get_tiling)) + ret = get_tiling_mode(bufmgr_gem, handle, + &bo_gem->tiling_mode, &bo_gem->swizzle_mode); + if (ret) goto err; - bo_gem->tiling_mode = get_tiling.tiling_mode; - bo_gem->swizzle_mode = get_tiling.swizzle_mode; /* XXX stride is unknown */ drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0); diff --git a/intel/meson.build b/intel/meson.build index 355bf35..4d3f1eb 100644 --- a/intel/meson.build +++ b/intel/meson.build @@ -92,9 +92,13 @@ test( find_program('tests/gen7-2d-copy.batch.sh'), workdir : meson.current_build_dir(), ) + test( - 'intel-symbol-check', - find_program('intel-symbol-check'), - env : env_test, - args : libdrm_intel, + 'intel-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_intel, + '--symbols-file', files('intel-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/intel/tests/.gitignore b/intel/tests/.gitignore new file mode 100644 index 0000000..e9d01ec --- /dev/null +++ b/intel/tests/.gitignore @@ -0,0 +1 @@ +*-new.txt diff --git a/intel/tests/gen4-3d.batch.sh b/intel/tests/gen4-3d.batch.sh deleted file mode 100755 index a94057f..0000000 --- a/intel/tests/gen4-3d.batch.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -TEST_FILENAME=`echo "$0" | sed 's|.sh||'` -./test_decode $TEST_FILENAME - -ret=$? - -# pretty-print a diff showing what happened, and leave the dumped -# around for possibly moving over the ref. -if test $ret = 1; then - REF_FILENAME="$TEST_FILENAME-ref.txt" - NEW_FILENAME="$TEST_FILENAME-new.txt" - ./test_decode $TEST_FILENAME -dump > $NEW_FILENAME - if test $? = 0; then - echo "Differences:" - diff -u $REF_FILENAME $NEW_FILENAME - fi -fi - -exit $ret diff --git a/intel/tests/gen4-3d.batch.sh b/intel/tests/gen4-3d.batch.sh new file mode 120000 index 0000000..796ca5f --- /dev/null +++ b/intel/tests/gen4-3d.batch.sh @@ -0,0 +1 @@ +test-batch.sh \ No newline at end of file diff --git a/intel/tests/gen5-3d.batch.sh b/intel/tests/gen5-3d.batch.sh deleted file mode 100755 index a94057f..0000000 --- a/intel/tests/gen5-3d.batch.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -TEST_FILENAME=`echo "$0" | sed 's|.sh||'` -./test_decode $TEST_FILENAME - -ret=$? - -# pretty-print a diff showing what happened, and leave the dumped -# around for possibly moving over the ref. -if test $ret = 1; then - REF_FILENAME="$TEST_FILENAME-ref.txt" - NEW_FILENAME="$TEST_FILENAME-new.txt" - ./test_decode $TEST_FILENAME -dump > $NEW_FILENAME - if test $? = 0; then - echo "Differences:" - diff -u $REF_FILENAME $NEW_FILENAME - fi -fi - -exit $ret diff --git a/intel/tests/gen5-3d.batch.sh b/intel/tests/gen5-3d.batch.sh new file mode 120000 index 0000000..796ca5f --- /dev/null +++ b/intel/tests/gen5-3d.batch.sh @@ -0,0 +1 @@ +test-batch.sh \ No newline at end of file diff --git a/intel/tests/gen6-3d.batch.sh b/intel/tests/gen6-3d.batch.sh deleted file mode 100755 index a94057f..0000000 --- a/intel/tests/gen6-3d.batch.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -TEST_FILENAME=`echo "$0" | sed 's|.sh||'` -./test_decode $TEST_FILENAME - -ret=$? - -# pretty-print a diff showing what happened, and leave the dumped -# around for possibly moving over the ref. -if test $ret = 1; then - REF_FILENAME="$TEST_FILENAME-ref.txt" - NEW_FILENAME="$TEST_FILENAME-new.txt" - ./test_decode $TEST_FILENAME -dump > $NEW_FILENAME - if test $? = 0; then - echo "Differences:" - diff -u $REF_FILENAME $NEW_FILENAME - fi -fi - -exit $ret diff --git a/intel/tests/gen6-3d.batch.sh b/intel/tests/gen6-3d.batch.sh new file mode 120000 index 0000000..796ca5f --- /dev/null +++ b/intel/tests/gen6-3d.batch.sh @@ -0,0 +1 @@ +test-batch.sh \ No newline at end of file diff --git a/intel/tests/gen7-2d-copy.batch.sh b/intel/tests/gen7-2d-copy.batch.sh deleted file mode 100755 index a94057f..0000000 --- a/intel/tests/gen7-2d-copy.batch.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -TEST_FILENAME=`echo "$0" | sed 's|.sh||'` -./test_decode $TEST_FILENAME - -ret=$? - -# pretty-print a diff showing what happened, and leave the dumped -# around for possibly moving over the ref. -if test $ret = 1; then - REF_FILENAME="$TEST_FILENAME-ref.txt" - NEW_FILENAME="$TEST_FILENAME-new.txt" - ./test_decode $TEST_FILENAME -dump > $NEW_FILENAME - if test $? = 0; then - echo "Differences:" - diff -u $REF_FILENAME $NEW_FILENAME - fi -fi - -exit $ret diff --git a/intel/tests/gen7-2d-copy.batch.sh b/intel/tests/gen7-2d-copy.batch.sh new file mode 120000 index 0000000..796ca5f --- /dev/null +++ b/intel/tests/gen7-2d-copy.batch.sh @@ -0,0 +1 @@ +test-batch.sh \ No newline at end of file diff --git a/intel/tests/gen7-3d.batch.sh b/intel/tests/gen7-3d.batch.sh deleted file mode 100755 index a94057f..0000000 --- a/intel/tests/gen7-3d.batch.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -TEST_FILENAME=`echo "$0" | sed 's|.sh||'` -./test_decode $TEST_FILENAME - -ret=$? - -# pretty-print a diff showing what happened, and leave the dumped -# around for possibly moving over the ref. -if test $ret = 1; then - REF_FILENAME="$TEST_FILENAME-ref.txt" - NEW_FILENAME="$TEST_FILENAME-new.txt" - ./test_decode $TEST_FILENAME -dump > $NEW_FILENAME - if test $? = 0; then - echo "Differences:" - diff -u $REF_FILENAME $NEW_FILENAME - fi -fi - -exit $ret diff --git a/intel/tests/gen7-3d.batch.sh b/intel/tests/gen7-3d.batch.sh new file mode 120000 index 0000000..796ca5f --- /dev/null +++ b/intel/tests/gen7-3d.batch.sh @@ -0,0 +1 @@ +test-batch.sh \ No newline at end of file diff --git a/intel/tests/gm45-3d.batch.sh b/intel/tests/gm45-3d.batch.sh deleted file mode 100755 index a94057f..0000000 --- a/intel/tests/gm45-3d.batch.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -TEST_FILENAME=`echo "$0" | sed 's|.sh||'` -./test_decode $TEST_FILENAME - -ret=$? - -# pretty-print a diff showing what happened, and leave the dumped -# around for possibly moving over the ref. -if test $ret = 1; then - REF_FILENAME="$TEST_FILENAME-ref.txt" - NEW_FILENAME="$TEST_FILENAME-new.txt" - ./test_decode $TEST_FILENAME -dump > $NEW_FILENAME - if test $? = 0; then - echo "Differences:" - diff -u $REF_FILENAME $NEW_FILENAME - fi -fi - -exit $ret diff --git a/intel/tests/gm45-3d.batch.sh b/intel/tests/gm45-3d.batch.sh new file mode 120000 index 0000000..796ca5f --- /dev/null +++ b/intel/tests/gm45-3d.batch.sh @@ -0,0 +1 @@ +test-batch.sh \ No newline at end of file diff --git a/libkms/Android.mk b/libkms/Android.mk new file mode 100644 index 0000000..a8b9489 --- /dev/null +++ b/libkms/Android.mk @@ -0,0 +1,51 @@ +DRM_GPU_DRIVERS := $(strip $(filter-out swrast, $(BOARD_GPU_DRIVERS))) + +intel_drivers := i915 i965 i915g iris +radeon_drivers := r300g r600g radeonsi +nouveau_drivers := nouveau +virgl_drivers := virgl +vmwgfx_drivers := vmwgfx + +valid_drivers := \ + $(intel_drivers) \ + $(radeon_drivers) \ + $(nouveau_drivers) \ + $(virgl_drivers) \ + $(vmwgfx_drivers) + +# warn about invalid drivers +invalid_drivers := $(filter-out $(valid_drivers), $(DRM_GPU_DRIVERS)) +ifneq ($(invalid_drivers),) +$(warning invalid GPU drivers: $(invalid_drivers)) +# tidy up +DRM_GPU_DRIVERS := $(filter-out $(invalid_drivers), $(DRM_GPU_DRIVERS)) +endif + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_SRC_FILES := $(LIBKMS_FILES) + +ifneq ($(filter $(vmwgfx_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += $(LIBKMS_VMWGFX_FILES) +endif + +ifneq ($(filter $(intel_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += $(LIBKMS_INTEL_FILES) +endif + +ifneq ($(filter $(nouveau_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += $(LIBKMS_NOUVEAU_FILES) +endif + +ifneq ($(filter $(radeon_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += $(LIBKMS_RADEON_FILES) +endif + +LOCAL_MODULE := libkms +LOCAL_SHARED_LIBRARIES := libdrm + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) diff --git a/libkms/kms-symbols.txt b/libkms/kms-symbols.txt new file mode 100644 index 0000000..e0ba8c9 --- /dev/null +++ b/libkms/kms-symbols.txt @@ -0,0 +1,8 @@ +kms_bo_create +kms_bo_destroy +kms_bo_get_prop +kms_bo_map +kms_bo_unmap +kms_create +kms_destroy +kms_get_prop diff --git a/libkms/meson.build b/libkms/meson.build index 04f018a..216be4d 100644 --- a/libkms/meson.build +++ b/libkms/meson.build @@ -68,8 +68,11 @@ pkg.generate( ) test( - 'kms-symbol-check', - find_program('kms-symbol-check'), - env : env_test, - args : libkms, + 'kms-symbols-check', + symbols_check, + args : [ + '--lib', libkms, + '--symbols-file', files('kms-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/meson.build b/meson.build index fc02f55..0515866 100644 --- a/meson.build +++ b/meson.build @@ -21,7 +21,7 @@ project( 'libdrm', ['c'], - version : '2.4.100', + version : '2.4.101', license : 'MIT', meson_version : '>= 0.43', default_options : ['buildtype=debugoptimized', 'c_std=gnu99'], @@ -44,14 +44,18 @@ dep_threads = dependency('threads') cc = meson.get_compiler('c') +symbols_check = find_program('symbols-check.py') +prog_nm = find_program('nm') + # Check for atomics intel_atomics = false lib_atomics = false dep_atomic_ops = dependency('atomic_ops', required : false) -if cc.compiles(''' +if cc.links(''' int atomic_add(int *i) { return __sync_add_and_fetch (i, 1); } int atomic_cmpxchg(int *i, int j, int k) { return __sync_val_compare_and_swap (i, j, k); } + int main() { } ''', name : 'Intel Atomics') intel_atomics = true @@ -183,7 +187,7 @@ dep_m = cc.find_library('m', required : false) # FreeBSD requires sys/types.h for sys/sysctl.h, add it as part of the # includes when checking for headers. foreach header : ['sys/sysctl.h', 'sys/select.h', 'alloca.h'] - config.set('HAVE_' + header.underscorify().to_upper(), + config.set10('HAVE_' + header.underscorify().to_upper(), cc.compiles('#include \n#include <@0@>'.format(header), name : '@0@ works'.format(header))) endforeach if (cc.has_header_symbol('sys/sysmacros.h', 'major') and @@ -281,7 +285,7 @@ config_file = configure_file( configuration : config, output : 'config.h', ) -add_project_arguments('-include', 'config.h', language : 'c') +add_project_arguments('-include', '@0@'.format(config_file), language : 'c') inc_root = include_directories('.') inc_drm = include_directories('include/drm') @@ -301,6 +305,16 @@ libdrm = shared_library( install : true, ) +test( + 'core-symbols-check', + symbols_check, + args : [ + '--lib', libdrm, + '--symbols-file', files('core-symbols.txt'), + '--nm', prog_nm.path(), + ], +) + ext_libdrm = declare_dependency( link_with : libdrm, include_directories : [inc_root, inc_drm], @@ -331,9 +345,6 @@ pkg.generate( description : 'Userspace interface to kernel DRM services', ) -env_test = environment() -env_test.set('NM', find_program('nm').path()) - if with_libkms subdir('libkms') endif diff --git a/nouveau/Android.mk b/nouveau/Android.mk new file mode 100644 index 0000000..b430af4 --- /dev/null +++ b/nouveau/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_NOUVEAU_FILES, LIBDRM_NOUVEAU_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_nouveau + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_NOUVEAU_FILES) + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) diff --git a/nouveau/meson.build b/nouveau/meson.build index 56e952c..9bd58fc 100644 --- a/nouveau/meson.build +++ b/nouveau/meson.build @@ -52,8 +52,11 @@ pkg.generate( ) test( - 'nouveau-symbol-check', - find_program('nouveau-symbol-check'), - env : env_test, - args : libdrm_nouveau, + 'nouveau-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_nouveau, + '--symbols-file', files('nouveau-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/nouveau/nouveau-symbols.txt b/nouveau/nouveau-symbols.txt new file mode 100644 index 0000000..ef8032f --- /dev/null +++ b/nouveau/nouveau-symbols.txt @@ -0,0 +1,41 @@ +nouveau_bo_map +nouveau_bo_name_get +nouveau_bo_name_ref +nouveau_bo_new +nouveau_bo_prime_handle_ref +nouveau_bo_ref +nouveau_bo_set_prime +nouveau_bo_wait +nouveau_bo_wrap +nouveau_bufctx_del +nouveau_bufctx_mthd +nouveau_bufctx_new +nouveau_bufctx_refn +nouveau_bufctx_reset +nouveau_client_del +nouveau_client_new +nouveau_device_del +nouveau_device_new +nouveau_device_open +nouveau_device_open_existing +nouveau_device_wrap +nouveau_drm_del +nouveau_drm_new +nouveau_getparam +nouveau_object_del +nouveau_object_mclass +nouveau_object_mthd +nouveau_object_new +nouveau_object_sclass_get +nouveau_object_sclass_put +nouveau_pushbuf_bufctx +nouveau_pushbuf_data +nouveau_pushbuf_del +nouveau_pushbuf_kick +nouveau_pushbuf_new +nouveau_pushbuf_refd +nouveau_pushbuf_refn +nouveau_pushbuf_reloc +nouveau_pushbuf_space +nouveau_pushbuf_validate +nouveau_setparam diff --git a/omap/Android.mk b/omap/Android.mk new file mode 100644 index 0000000..b25cca1 --- /dev/null +++ b/omap/Android.mk @@ -0,0 +1,13 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE := libdrm_omap +LOCAL_VENDOR_MODULE := true + +LOCAL_SRC_FILES := omap_drm.c + +LOCAL_SHARED_LIBRARIES := libdrm + +include $(LIBDRM_COMMON_MK) + +include $(BUILD_SHARED_LIBRARY) diff --git a/omap/meson.build b/omap/meson.build index f3ea36d..53330b6 100644 --- a/omap/meson.build +++ b/omap/meson.build @@ -47,8 +47,11 @@ pkg.generate( ) test( - 'omap-symbol-check', - find_program('omap-symbol-check'), - env : env_test, - args : libdrm_omap, + 'omap-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_omap, + '--symbols-file', files('omap-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/omap/omap-symbols.txt b/omap/omap-symbols.txt new file mode 100644 index 0000000..749d0f7 --- /dev/null +++ b/omap/omap-symbols.txt @@ -0,0 +1,18 @@ +omap_bo_cpu_fini +omap_bo_cpu_prep +omap_bo_del +omap_bo_dmabuf +omap_bo_from_dmabuf +omap_bo_from_name +omap_bo_get_name +omap_bo_handle +omap_bo_map +omap_bo_new +omap_bo_new_tiled +omap_bo_ref +omap_bo_size +omap_device_del +omap_device_new +omap_device_ref +omap_get_param +omap_set_param diff --git a/radeon/Android.mk b/radeon/Android.mk new file mode 100644 index 0000000..71040da --- /dev/null +++ b/radeon/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_RADEON_FILES, LIBDRM_RADEON_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_radeon + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_RADEON_FILES) + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) diff --git a/radeon/meson.build b/radeon/meson.build index 662b5bc..ca12832 100644 --- a/radeon/meson.build +++ b/radeon/meson.build @@ -57,8 +57,11 @@ pkg.generate( ) test( - 'radeon-symbol-check', - find_program('radeon-symbol-check'), - env : env_test, - args : libdrm_radeon, + 'radeon-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_radeon, + '--symbols-file', files('radeon-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/radeon/radeon-symbols.txt b/radeon/radeon-symbols.txt new file mode 100644 index 0000000..5a532d8 --- /dev/null +++ b/radeon/radeon-symbols.txt @@ -0,0 +1,44 @@ +radeon_bo_debug +radeon_bo_get_handle +radeon_bo_get_src_domain +radeon_bo_get_tiling +radeon_bo_is_busy +radeon_bo_is_referenced_by_cs +radeon_bo_is_static +radeon_bo_manager_gem_ctor +radeon_bo_manager_gem_dtor +radeon_bo_map +radeon_bo_open +radeon_bo_ref +radeon_bo_set_tiling +radeon_bo_unmap +radeon_bo_unref +radeon_bo_wait +radeon_cs_begin +radeon_cs_create +radeon_cs_destroy +radeon_cs_emit +radeon_cs_end +radeon_cs_erase +radeon_cs_get_id +radeon_cs_manager_gem_ctor +radeon_cs_manager_gem_dtor +radeon_cs_need_flush +radeon_cs_print +radeon_cs_set_limit +radeon_cs_space_add_persistent_bo +radeon_cs_space_check +radeon_cs_space_check_with_bo +radeon_cs_space_reset_bos +radeon_cs_space_set_flush +radeon_cs_write_reloc +radeon_gem_bo_open_prime +radeon_gem_get_kernel_name +radeon_gem_get_reloc_in_cs +radeon_gem_name_bo +radeon_gem_prime_share_bo +radeon_gem_set_domain +radeon_surface_best +radeon_surface_init +radeon_surface_manager_free +radeon_surface_manager_new diff --git a/symbols-check.py b/symbols-check.py new file mode 100644 index 0000000..2e7ba68 --- /dev/null +++ b/symbols-check.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 + +import argparse +import os +import platform +import subprocess + +# This list contains symbols that _might_ be exported for some platforms +PLATFORM_SYMBOLS = [ + '__bss_end__', + '__bss_start__', + '__bss_start', + '__end__', + '_bss_end__', + '_edata', + '_end', + '_fini', + '_init', +] + + +def get_symbols(nm, lib): + ''' + List all the (non platform-specific) symbols exported by the library + ''' + symbols = [] + platform_name = platform.system() + output = subprocess.check_output([nm, '-gP', lib], + stderr=open(os.devnull, 'w')).decode("ascii") + for line in output.splitlines(): + fields = line.split() + if len(fields) == 2 or fields[1] == 'U': + continue + symbol_name = fields[0] + if platform_name == 'Linux': + if symbol_name in PLATFORM_SYMBOLS: + continue + elif platform_name == 'Darwin': + assert symbol_name[0] == '_' + symbol_name = symbol_name[1:] + symbols.append(symbol_name) + + return symbols + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--symbols-file', + action='store', + required=True, + help='path to file containing symbols') + parser.add_argument('--lib', + action='store', + required=True, + help='path to library') + parser.add_argument('--nm', + action='store', + required=True, + help='path to binary (or name in $PATH)') + args = parser.parse_args() + + try: + lib_symbols = get_symbols(args.nm, args.lib) + except: + # We can't run this test, but we haven't technically failed it either + # Return the GNU "skip" error code + exit(77) + mandatory_symbols = [] + optional_symbols = [] + with open(args.symbols_file) as symbols_file: + qualifier_optional = '(optional)' + for line in symbols_file.readlines(): + + # Strip comments + line = line.split('#')[0] + line = line.strip() + if not line: + continue + + # Line format: + # [qualifier] symbol + qualifier = None + symbol = None + + fields = line.split() + if len(fields) == 1: + symbol = fields[0] + elif len(fields) == 2: + qualifier = fields[0] + symbol = fields[1] + else: + print(args.symbols_file + ': invalid format: ' + line) + exit(1) + + # The only supported qualifier is 'optional', which means the + # symbol doesn't have to be exported by the library + if qualifier and not qualifier == qualifier_optional: + print(args.symbols_file + ': invalid qualifier: ' + qualifier) + exit(1) + + if qualifier == qualifier_optional: + optional_symbols.append(symbol) + else: + mandatory_symbols.append(symbol) + + unknown_symbols = [] + for symbol in lib_symbols: + if symbol in mandatory_symbols: + continue + if symbol in optional_symbols: + continue + unknown_symbols.append(symbol) + + missing_symbols = [ + sym for sym in mandatory_symbols if sym not in lib_symbols + ] + + for symbol in unknown_symbols: + print(args.lib + ': unknown symbol exported: ' + symbol) + + for symbol in missing_symbols: + print(args.lib + ': missing symbol: ' + symbol) + + if unknown_symbols or missing_symbols: + exit(1) + exit(0) + + +if __name__ == '__main__': + main() diff --git a/tegra/.gitignore b/tegra/.gitignore new file mode 100644 index 0000000..74cfe47 --- /dev/null +++ b/tegra/.gitignore @@ -0,0 +1 @@ +libdrm_tegra.pc diff --git a/tegra/meson.build b/tegra/meson.build index ce56ddc..88613b9 100644 --- a/tegra/meson.build +++ b/tegra/meson.build @@ -46,8 +46,11 @@ pkg.generate( ) test( - 'tegra-symbol-check', - find_program('tegra-symbol-check'), - env : env_test, - args : libdrm_tegra, + 'tegra-symbols-check', + symbols_check, + args : [ + '--lib', libdrm_tegra, + '--symbols-file', files('tegra-symbols.txt'), + '--nm', prog_nm.path(), + ], ) diff --git a/tegra/tegra-symbols.txt b/tegra/tegra-symbols.txt new file mode 100644 index 0000000..5e3e955 --- /dev/null +++ b/tegra/tegra-symbols.txt @@ -0,0 +1,13 @@ +drm_tegra_bo_get_flags +drm_tegra_bo_get_handle +drm_tegra_bo_get_tiling +drm_tegra_bo_map +drm_tegra_bo_new +drm_tegra_bo_ref +drm_tegra_bo_set_flags +drm_tegra_bo_set_tiling +drm_tegra_bo_unmap +drm_tegra_bo_unref +drm_tegra_bo_wrap +drm_tegra_close +drm_tegra_new diff --git a/tests/Android.mk b/tests/Android.mk new file mode 100644 index 0000000..5053e7d --- /dev/null +++ b/tests/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/tests/amdgpu/.editorconfig b/tests/amdgpu/.editorconfig new file mode 120000 index 0000000..70734e4 --- /dev/null +++ b/tests/amdgpu/.editorconfig @@ -0,0 +1 @@ +../../amdgpu/.editorconfig \ No newline at end of file diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c index 5aadd7e..47e1676 100644 --- a/tests/amdgpu/amdgpu_test.c +++ b/tests/amdgpu/amdgpu_test.c @@ -202,44 +202,42 @@ static void display_test_suites(void) CU_pSuite pSuite = NULL; CU_pTest pTest = NULL; - printf("Suites\n"); + printf("%5s: %2s: %8s: %s\n", "What", "ID", "Status", "Name"); for (iSuite = 0; suites[iSuite].pName != NULL; iSuite++) { pSuite = CU_get_suite_by_index((unsigned int) iSuite + 1, - CU_get_registry()); + CU_get_registry()); if (!pSuite) { fprintf(stderr, "Invalid suite id : %d\n", iSuite + 1); continue; } - printf("Suite id = %d: Name '%s status: %s'\n", - iSuite + 1, suites[iSuite].pName, - pSuite->fActive ? "ENABLED" : "DISABLED"); - + printf("Suite: %2d: %8s: %s\n", + iSuite + 1, + pSuite->fActive ? "ENABLED" : "DISABLED", + suites[iSuite].pName); + if (!pSuite->fActive) + continue; for (iTest = 0; suites[iSuite].pTests[iTest].pName != NULL; - iTest++) { - + iTest++) { pTest = CU_get_test_by_index((unsigned int) iTest + 1, - pSuite); - + pSuite); if (!pTest) { fprintf(stderr, "Invalid test id : %d\n", iTest + 1); continue; } - - printf("Test id %d: Name: '%s status: %s'\n", iTest + 1, - suites[iSuite].pTests[iTest].pName, - pSuite->fActive && pTest->fActive ? - "ENABLED" : "DISABLED"); + printf(" Test: %2d: %8s: %s\n", + iTest + 1, + pSuite->fActive && pTest->fActive ? "ENABLED" : "DISABLED", + suites[iSuite].pTests[iTest].pName); } } } - /** Help string for command line parameters */ static const char usage[] = "Usage: %s [-hlpr] [<-s > [-t ] [-f]] " @@ -452,6 +450,41 @@ static void amdgpu_disable_suites() "sdma ring block test (set amdgpu.lockup_timeout=50)", CU_FALSE)) fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + /* This test was ran on GFX9 only */ + //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) + if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, + "gfx ring bad dispatch test (set amdgpu.lockup_timeout=50)", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + + /* This test was ran on GFX9 only */ + //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) + if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, + "compute ring bad dispatch test (set amdgpu.lockup_timeout=50,50)", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + + /* This test was ran on GFX9 only */ + //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) + if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, + "gfx ring bad slow dispatch test (set amdgpu.lockup_timeout=50)", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + + /* This test was ran on GFX9 only */ + //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) + if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, + "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + + //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) + if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, + "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + + /* This test was ran on GFX9 only */ + //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) + if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, + "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + if (amdgpu_set_test_active(BO_TESTS_STR, "Metadata", CU_FALSE)) fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h index 36675ea..f549225 100644 --- a/tests/amdgpu/amdgpu_test.h +++ b/tests/amdgpu/amdgpu_test.h @@ -236,6 +236,11 @@ CU_BOOL suite_syncobj_timeline_tests_enable(void); */ extern CU_TestInfo syncobj_timeline_tests[]; +void amdgpu_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip_type); +void amdgpu_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip_type); +void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t ring, + int hang); +void amdgpu_memcpy_draw_hang_slow_test(amdgpu_device_handle device_handle, uint32_t ring); /** * Helper functions diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c index ab2a672..57496c8 100644 --- a/tests/amdgpu/basic_tests.c +++ b/tests/amdgpu/basic_tests.c @@ -30,7 +30,7 @@ #endif #include #include -#ifdef HAVE_ALLOCA_H +#if HAVE_ALLOCA_H # include #endif #include @@ -86,7 +86,7 @@ CU_TestInfo basic_tests[] = { { "GPU reset Test", amdgpu_gpu_reset_test }, CU_TEST_INFO_NULL, }; -#define BUFFER_SIZE (8 * 1024) +#define BUFFER_SIZE (MAX2(8 * 1024, getpagesize())) #define SDMA_PKT_HEADER_op_offset 0 #define SDMA_PKT_HEADER_op_mask 0x000000FF #define SDMA_PKT_HEADER_op_shift 0 @@ -306,7 +306,9 @@ static uint32_t shader_bin[] = { enum cs_type { CS_BUFFERCLEAR, - CS_BUFFERCOPY + CS_BUFFERCOPY, + CS_HANG, + CS_HANG_SLOW }; static const uint32_t bufferclear_cs_shader_gfx9[] = { @@ -355,7 +357,9 @@ static const uint32_t preamblecache_gfx9[] = { enum ps_type { PS_CONST, - PS_TEX + PS_TEX, + PS_HANG, + PS_HANG_SLOW }; static const uint32_t ps_const_shader_gfx9[] = { @@ -461,13 +465,67 @@ static const uint32_t cached_cmd_gfx9[] = { 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0, 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020, 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf, - 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x1a, + 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x12, 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0, 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011, 0xc0026900, 0x292, 0x20, 0x60201b8, 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0 }; +unsigned int memcpy_ps_hang[] = { + 0xFFFFFFFF, 0xBEFE0A7E, 0xBEFC0304, 0xC0C20100, + 0xC0800300, 0xC8080000, 0xC80C0100, 0xC8090001, + 0xC80D0101, 0xBF8C007F, 0xF0800F00, 0x00010002, + 0xBEFE040C, 0xBF8C0F70, 0xBF800000, 0xBF800000, + 0xF800180F, 0x03020100, 0xBF810000 +}; + +struct amdgpu_test_shader { + uint32_t *shader; + uint32_t header_length; + uint32_t body_length; + uint32_t foot_length; +}; + +unsigned int memcpy_cs_hang_slow_ai_codes[] = { + 0xd1fd0000, 0x04010c08, 0xe00c2000, 0x80000100, + 0xbf8c0f70, 0xe01c2000, 0x80010100, 0xbf810000 +}; + +struct amdgpu_test_shader memcpy_cs_hang_slow_ai = { + memcpy_cs_hang_slow_ai_codes, + 4, + 3, + 1 +}; + +unsigned int memcpy_cs_hang_slow_rv_codes[] = { + 0x8e00860c, 0x32000000, 0xe00c2000, 0x80010100, + 0xbf8c0f70, 0xe01c2000, 0x80020100, 0xbf810000 +}; + +struct amdgpu_test_shader memcpy_cs_hang_slow_rv = { + memcpy_cs_hang_slow_rv_codes, + 4, + 3, + 1 +}; + +unsigned int memcpy_ps_hang_slow_ai_codes[] = { + 0xbefc000c, 0xbe8e017e, 0xbefe077e, 0xd4080000, + 0xd4090001, 0xd40c0100, 0xd40d0101, 0xf0800f00, + 0x00400002, 0xbefe010e, 0xbf8c0f70, 0xbf800000, + 0xbf800000, 0xbf800000, 0xbf800000, 0xc400180f, + 0x03020100, 0xbf810000 +}; + +struct amdgpu_test_shader memcpy_ps_hang_slow_ai = { + memcpy_ps_hang_slow_ai_codes, + 7, + 2, + 9 +}; + int amdgpu_bo_alloc_and_map_raw(amdgpu_device_handle dev, unsigned size, unsigned alignment, unsigned heap, uint64_t alloc_flags, uint64_t mapping_flags, amdgpu_bo_handle *bo, void **cpu, @@ -2065,6 +2123,37 @@ static void amdgpu_sync_dependency_test(void) free(ibs_request.dependencies); } +static int amdgpu_dispatch_load_cs_shader_hang_slow(uint32_t *ptr, int family) +{ + struct amdgpu_test_shader *shader; + int i, loop = 0x10000; + + switch (family) { + case AMDGPU_FAMILY_AI: + shader = &memcpy_cs_hang_slow_ai; + break; + case AMDGPU_FAMILY_RV: + shader = &memcpy_cs_hang_slow_rv; + break; + default: + return -1; + break; + } + + memcpy(ptr, shader->shader, shader->header_length * sizeof(uint32_t)); + + for (i = 0; i < loop; i++) + memcpy(ptr + shader->header_length + shader->body_length * i, + shader->shader + shader->header_length, + shader->body_length * sizeof(uint32_t)); + + memcpy(ptr + shader->header_length + shader->body_length * loop, + shader->shader + shader->header_length + shader->body_length, + shader->foot_length * sizeof(uint32_t)); + + return 0; +} + static int amdgpu_dispatch_load_cs_shader(uint8_t *ptr, int cs_type) { @@ -2080,6 +2169,10 @@ static int amdgpu_dispatch_load_cs_shader(uint8_t *ptr, shader = buffercopy_cs_shader_gfx9; shader_size = sizeof(buffercopy_cs_shader_gfx9); break; + case CS_HANG: + shader = memcpy_ps_hang; + shader_size = sizeof(memcpy_ps_hang); + break; default: return -1; break; @@ -2300,7 +2393,8 @@ static void amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle, static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle, uint32_t ip_type, - uint32_t ring) + uint32_t ring, + int hang) { amdgpu_context_handle context_handle; amdgpu_bo_handle bo_src, bo_dst, bo_shader, bo_cmd, resources[4]; @@ -2316,7 +2410,8 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle, int bo_cmd_size = 4096; struct amdgpu_cs_request ibs_request = {0}; struct amdgpu_cs_ib_info ib_info= {0}; - uint32_t expired; + uint32_t expired, hang_state, hangs; + enum cs_type cs_type; amdgpu_bo_list_handle bo_list; struct amdgpu_cs_fence fence_status = {0}; @@ -2337,7 +2432,8 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle, CU_ASSERT_EQUAL(r, 0); memset(ptr_shader, 0, bo_shader_size); - r = amdgpu_dispatch_load_cs_shader(ptr_shader, CS_BUFFERCOPY ); + cs_type = hang ? CS_HANG : CS_BUFFERCOPY; + r = amdgpu_dispatch_load_cs_shader(ptr_shader, cs_type); CU_ASSERT_EQUAL(r, 0); r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, @@ -2423,14 +2519,21 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle, r = amdgpu_cs_query_fence_status(&fence_status, AMDGPU_TIMEOUT_INFINITE, 0, &expired); - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(expired, true); - /* verify if memcpy test result meets with expected */ - i = 0; - while(i < bo_dst_size) { - CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]); - i++; + if (!hang) { + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(expired, true); + + /* verify if memcpy test result meets with expected */ + i = 0; + while(i < bo_dst_size) { + CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]); + i++; + } + } else { + r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); } r = amdgpu_bo_list_destroy(bo_list); @@ -2464,7 +2567,7 @@ static void amdgpu_compute_dispatch_test(void) for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { amdgpu_memset_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id); - amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id); + amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id, 0); } } @@ -2481,8 +2584,224 @@ static void amdgpu_gfx_dispatch_test(void) for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { amdgpu_memset_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id); - amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id); + amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id, 0); + } +} + +void amdgpu_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip_type) +{ + int r; + struct drm_amdgpu_info_hw_ip info; + uint32_t ring_id; + + r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &info); + CU_ASSERT_EQUAL(r, 0); + if (!info.available_rings) + printf("SKIP ... as there's no ring for ip %d\n", ip_type); + + for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { + amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0); + amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 1); + amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0); + } +} + +static void amdgpu_memcpy_dispatch_hang_slow_test(amdgpu_device_handle device_handle, + uint32_t ip_type, uint32_t ring) +{ + amdgpu_context_handle context_handle; + amdgpu_bo_handle bo_src, bo_dst, bo_shader, bo_cmd, resources[4]; + volatile unsigned char *ptr_dst; + void *ptr_shader; + unsigned char *ptr_src; + uint32_t *ptr_cmd; + uint64_t mc_address_src, mc_address_dst, mc_address_shader, mc_address_cmd; + amdgpu_va_handle va_src, va_dst, va_shader, va_cmd; + int i, r; + int bo_dst_size = 0x4000000; + int bo_shader_size = 0x400000; + int bo_cmd_size = 4096; + struct amdgpu_cs_request ibs_request = {0}; + struct amdgpu_cs_ib_info ib_info= {0}; + uint32_t hang_state, hangs, expired; + struct amdgpu_gpu_info gpu_info = {0}; + amdgpu_bo_list_handle bo_list; + struct amdgpu_cs_fence fence_status = {0}; + + r = amdgpu_query_gpu_info(device_handle, &gpu_info); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_cs_ctx_create(device_handle, &context_handle); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, + &bo_cmd, (void **)&ptr_cmd, + &mc_address_cmd, &va_cmd); + CU_ASSERT_EQUAL(r, 0); + memset(ptr_cmd, 0, bo_cmd_size); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, + &bo_shader, &ptr_shader, + &mc_address_shader, &va_shader); + CU_ASSERT_EQUAL(r, 0); + memset(ptr_shader, 0, bo_shader_size); + + r = amdgpu_dispatch_load_cs_shader_hang_slow(ptr_shader, gpu_info.family_id); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, + &bo_src, (void **)&ptr_src, + &mc_address_src, &va_src); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, + &bo_dst, (void **)&ptr_dst, + &mc_address_dst, &va_dst); + CU_ASSERT_EQUAL(r, 0); + + memset(ptr_src, 0x55, bo_dst_size); + + i = 0; + i += amdgpu_dispatch_init(ptr_cmd + i, ip_type); + + /* Issue commands to set cu mask used in current dispatch */ + i += amdgpu_dispatch_write_cumask(ptr_cmd + i); + + /* Writes shader state to HW */ + i += amdgpu_dispatch_write2hw(ptr_cmd + i, mc_address_shader); + + /* Write constant data */ + /* Writes the texture resource constants data to the SGPRs */ + ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4); + ptr_cmd[i++] = 0x240; + ptr_cmd[i++] = mc_address_src; + ptr_cmd[i++] = (mc_address_src >> 32) | 0x100000; + ptr_cmd[i++] = 0x400000; + ptr_cmd[i++] = 0x74fac; + + /* Writes the UAV constant data to the SGPRs. */ + ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4); + ptr_cmd[i++] = 0x244; + ptr_cmd[i++] = mc_address_dst; + ptr_cmd[i++] = (mc_address_dst >> 32) | 0x100000; + ptr_cmd[i++] = 0x400000; + ptr_cmd[i++] = 0x74fac; + + /* clear mmCOMPUTE_RESOURCE_LIMITS */ + ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1); + ptr_cmd[i++] = 0x215; + ptr_cmd[i++] = 0; + + /* dispatch direct command */ + ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3); + ptr_cmd[i++] = 0x10000; + ptr_cmd[i++] = 1; + ptr_cmd[i++] = 1; + ptr_cmd[i++] = 1; + + while (i & 7) + ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ + + resources[0] = bo_shader; + resources[1] = bo_src; + resources[2] = bo_dst; + resources[3] = bo_cmd; + r = amdgpu_bo_list_create(device_handle, 4, resources, NULL, &bo_list); + CU_ASSERT_EQUAL(r, 0); + + ib_info.ib_mc_address = mc_address_cmd; + ib_info.size = i; + ibs_request.ip_type = ip_type; + ibs_request.ring = ring; + ibs_request.resources = bo_list; + ibs_request.number_of_ibs = 1; + ibs_request.ibs = &ib_info; + ibs_request.fence_info.handle = NULL; + r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); + CU_ASSERT_EQUAL(r, 0); + + fence_status.ip_type = ip_type; + fence_status.ip_instance = 0; + fence_status.ring = ring; + fence_status.context = context_handle; + fence_status.fence = ibs_request.seq_no; + + /* wait for IB accomplished */ + r = amdgpu_cs_query_fence_status(&fence_status, + AMDGPU_TIMEOUT_INFINITE, + 0, &expired); + + r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); + + r = amdgpu_bo_list_destroy(bo_list); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(bo_src, va_src, mc_address_src, bo_dst_size); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_dst_size); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(bo_shader, va_shader, mc_address_shader, bo_shader_size); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_cs_ctx_free(context_handle); + CU_ASSERT_EQUAL(r, 0); +} + +void amdgpu_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip_type) +{ + int r; + struct drm_amdgpu_info_hw_ip info; + uint32_t ring_id; + + r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &info); + CU_ASSERT_EQUAL(r, 0); + if (!info.available_rings) + printf("SKIP ... as there's no ring for ip %d\n", ip_type); + + for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { + amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0); + amdgpu_memcpy_dispatch_hang_slow_test(device_handle, ip_type, ring_id); + amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0); + } +} + +static int amdgpu_draw_load_ps_shader_hang_slow(uint32_t *ptr, int family) +{ + struct amdgpu_test_shader *shader; + int i, loop = 0x40000; + + switch (family) { + case AMDGPU_FAMILY_AI: + case AMDGPU_FAMILY_RV: + shader = &memcpy_ps_hang_slow_ai; + break; + default: + return -1; + break; } + + memcpy(ptr, shader->shader, shader->header_length * sizeof(uint32_t)); + + for (i = 0; i < loop; i++) + memcpy(ptr + shader->header_length + shader->body_length * i, + shader->shader + shader->header_length, + shader->body_length * sizeof(uint32_t)); + + memcpy(ptr + shader->header_length + shader->body_length * loop, + shader->shader + shader->header_length + shader->body_length, + shader->foot_length * sizeof(uint32_t)); + + return 0; } static int amdgpu_draw_load_ps_shader(uint8_t *ptr, int ps_type) @@ -2510,6 +2829,12 @@ static int amdgpu_draw_load_ps_shader(uint8_t *ptr, int ps_type) patchinfo_code_size = ps_tex_shader_patchinfo_code_size_gfx9; patchcode_offset = ps_tex_shader_patchinfo_offset_gfx9; break; + case PS_HANG: + shader = memcpy_ps_hang; + shader_size = sizeof(memcpy_ps_hang); + + memcpy(ptr, shader, shader_size); + return 0; default: return -1; break; @@ -2566,7 +2891,8 @@ static int amdgpu_draw_init(uint32_t *ptr) } static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr, - uint64_t dst_addr) + uint64_t dst_addr, + int hang_slow) { int i = 0; @@ -2591,7 +2917,7 @@ static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr, ptr[i++] = 0x318; ptr[i++] = dst_addr >> 8; ptr[i++] = dst_addr >> 40; - ptr[i++] = 0x7c01f; + ptr[i++] = hang_slow ? 0x1ffc7ff : 0x7c01f; ptr[i++] = 0; ptr[i++] = 0x50438; ptr[i++] = 0x10140000; @@ -2600,7 +2926,7 @@ static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr, /* mmCB_MRT0_EPITCH */ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); ptr[i++] = 0x1e8; - ptr[i++] = 0x1f; + ptr[i++] = hang_slow ? 0x7ff : 0x1f; /* 0xA32B CB_COLOR1_BASE */ ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); @@ -2626,7 +2952,7 @@ static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr, return i; } -static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr) +static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr, int hang_slow) { int i = 0; const uint32_t *cached_cmd_ptr; @@ -2658,6 +2984,8 @@ static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr) cached_cmd_size = sizeof(cached_cmd_gfx9); memcpy(ptr + i, cached_cmd_ptr, cached_cmd_size); + if (hang_slow) + *(ptr + i + 12) = 0x8000800; i += cached_cmd_size/sizeof(uint32_t); return i; @@ -2665,7 +2993,8 @@ static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr) static int amdgpu_draw_vs_RectPosTexFast_write2hw(uint32_t *ptr, int ps_type, - uint64_t shader_addr) + uint64_t shader_addr, + int hang_slow) { int i = 0; @@ -2707,8 +3036,8 @@ static int amdgpu_draw_vs_RectPosTexFast_write2hw(uint32_t *ptr, ptr[i++] = PACKET3(PKT3_SET_SH_REG, 4); ptr[i++] = 0x4c; i += 2; - ptr[i++] = 0x42000000; - ptr[i++] = 0x42000000; + ptr[i++] = hang_slow ? 0x45000000 : 0x42000000; + ptr[i++] = hang_slow ? 0x45000000 : 0x42000000; ptr[i++] = PACKET3(PKT3_SET_SH_REG, 4); ptr[i++] = 0x50; @@ -2845,11 +3174,11 @@ void amdgpu_memset_draw(amdgpu_device_handle device_handle, i = 0; i += amdgpu_draw_init(ptr_cmd + i); - i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst); + i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 0); - i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i); + i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 0); - i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_CONST, mc_address_shader_vs); + i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_CONST, mc_address_shader_vs, 0); i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_CONST, mc_address_shader_ps); @@ -2869,7 +3198,7 @@ void amdgpu_memset_draw(amdgpu_device_handle device_handle, resources[1] = bo_shader_ps; resources[2] = bo_shader_vs; resources[3] = bo_cmd; - r = amdgpu_bo_list_create(device_handle, 3, resources, NULL, &bo_list); + r = amdgpu_bo_list_create(device_handle, 4, resources, NULL, &bo_list); CU_ASSERT_EQUAL(r, 0); ib_info.ib_mc_address = mc_address_cmd; @@ -2963,7 +3292,7 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle, amdgpu_bo_handle bo_shader_vs, uint64_t mc_address_shader_ps, uint64_t mc_address_shader_vs, - uint32_t ring) + uint32_t ring, int hang) { amdgpu_context_handle context_handle; amdgpu_bo_handle bo_dst, bo_src, bo_cmd, resources[5]; @@ -2977,7 +3306,8 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle, int bo_cmd_size = 4096; struct amdgpu_cs_request ibs_request = {0}; struct amdgpu_cs_ib_info ib_info= {0}; - uint32_t hang_state, hangs, expired; + uint32_t hang_state, hangs; + uint32_t expired; amdgpu_bo_list_handle bo_list; struct amdgpu_cs_fence fence_status = {0}; @@ -3008,11 +3338,11 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle, i = 0; i += amdgpu_draw_init(ptr_cmd + i); - i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst); + i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 0); - i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i); + i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 0); - i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_vs); + i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_vs, 0); i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_ps); @@ -3068,14 +3398,20 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle, r = amdgpu_cs_query_fence_status(&fence_status, AMDGPU_TIMEOUT_INFINITE, 0, &expired); - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(expired, true); + if (!hang) { + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(expired, true); - /* verify if memcpy test result meets with expected */ - i = 0; - while(i < bo_size) { - CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]); - i++; + /* verify if memcpy test result meets with expected */ + i = 0; + while(i < bo_size) { + CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]); + i++; + } + } else { + r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); } r = amdgpu_bo_list_destroy(bo_list); @@ -3093,7 +3429,8 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle, CU_ASSERT_EQUAL(r, 0); } -static void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t ring) +void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t ring, + int hang) { amdgpu_bo_handle bo_shader_ps, bo_shader_vs; void *ptr_shader_ps; @@ -3101,6 +3438,7 @@ static void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t uint64_t mc_address_shader_ps, mc_address_shader_vs; amdgpu_va_handle va_shader_ps, va_shader_vs; int bo_shader_size = 4096; + enum ps_type ps_type = hang ? PS_HANG : PS_TEX; int r; r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, @@ -3117,14 +3455,14 @@ static void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t CU_ASSERT_EQUAL(r, 0); memset(ptr_shader_vs, 0, bo_shader_size); - r = amdgpu_draw_load_ps_shader(ptr_shader_ps, PS_TEX); + r = amdgpu_draw_load_ps_shader(ptr_shader_ps, ps_type); CU_ASSERT_EQUAL(r, 0); r = amdgpu_draw_load_vs_shader(ptr_shader_vs); CU_ASSERT_EQUAL(r, 0); amdgpu_memcpy_draw(device_handle, bo_shader_ps, bo_shader_vs, - mc_address_shader_ps, mc_address_shader_vs, ring); + mc_address_shader_ps, mc_address_shader_vs, ring, hang); r = amdgpu_bo_unmap_and_free(bo_shader_ps, va_shader_ps, mc_address_shader_ps, bo_shader_size); CU_ASSERT_EQUAL(r, 0); @@ -3146,10 +3484,172 @@ static void amdgpu_draw_test(void) for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { amdgpu_memset_draw_test(device_handle, ring_id); - amdgpu_memcpy_draw_test(device_handle, ring_id); + amdgpu_memcpy_draw_test(device_handle, ring_id, 0); } } +void amdgpu_memcpy_draw_hang_slow_test(amdgpu_device_handle device_handle, uint32_t ring) +{ + amdgpu_context_handle context_handle; + amdgpu_bo_handle bo_shader_ps, bo_shader_vs; + amdgpu_bo_handle bo_dst, bo_src, bo_cmd, resources[5]; + void *ptr_shader_ps; + void *ptr_shader_vs; + volatile unsigned char *ptr_dst; + unsigned char *ptr_src; + uint32_t *ptr_cmd; + uint64_t mc_address_dst, mc_address_src, mc_address_cmd; + uint64_t mc_address_shader_ps, mc_address_shader_vs; + amdgpu_va_handle va_shader_ps, va_shader_vs; + amdgpu_va_handle va_dst, va_src, va_cmd; + struct amdgpu_gpu_info gpu_info = {0}; + int i, r; + int bo_size = 0x4000000; + int bo_shader_ps_size = 0x400000; + int bo_shader_vs_size = 4096; + int bo_cmd_size = 4096; + struct amdgpu_cs_request ibs_request = {0}; + struct amdgpu_cs_ib_info ib_info= {0}; + uint32_t hang_state, hangs, expired; + amdgpu_bo_list_handle bo_list; + struct amdgpu_cs_fence fence_status = {0}; + + r = amdgpu_query_gpu_info(device_handle, &gpu_info); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_cs_ctx_create(device_handle, &context_handle); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, + &bo_cmd, (void **)&ptr_cmd, + &mc_address_cmd, &va_cmd); + CU_ASSERT_EQUAL(r, 0); + memset(ptr_cmd, 0, bo_cmd_size); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_ps_size, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, + &bo_shader_ps, &ptr_shader_ps, + &mc_address_shader_ps, &va_shader_ps); + CU_ASSERT_EQUAL(r, 0); + memset(ptr_shader_ps, 0, bo_shader_ps_size); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_vs_size, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, + &bo_shader_vs, &ptr_shader_vs, + &mc_address_shader_vs, &va_shader_vs); + CU_ASSERT_EQUAL(r, 0); + memset(ptr_shader_vs, 0, bo_shader_vs_size); + + r = amdgpu_draw_load_ps_shader_hang_slow(ptr_shader_ps, gpu_info.family_id); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_draw_load_vs_shader(ptr_shader_vs); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, + &bo_src, (void **)&ptr_src, + &mc_address_src, &va_src); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096, + AMDGPU_GEM_DOMAIN_VRAM, 0, + &bo_dst, (void **)&ptr_dst, + &mc_address_dst, &va_dst); + CU_ASSERT_EQUAL(r, 0); + + memset(ptr_src, 0x55, bo_size); + + i = 0; + i += amdgpu_draw_init(ptr_cmd + i); + + i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 1); + + i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 1); + + i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_TEX, + mc_address_shader_vs, 1); + + i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_ps); + + ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 8); + ptr_cmd[i++] = 0xc; + ptr_cmd[i++] = mc_address_src >> 8; + ptr_cmd[i++] = mc_address_src >> 40 | 0x10e00000; + ptr_cmd[i++] = 0x1ffc7ff; + ptr_cmd[i++] = 0x90500fac; + ptr_cmd[i++] = 0xffe000; + i += 3; + + ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 4); + ptr_cmd[i++] = 0x14; + ptr_cmd[i++] = 0x92; + i += 3; + + ptr_cmd[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr_cmd[i++] = 0x191; + ptr_cmd[i++] = 0; + + i += amdgpu_draw_draw(ptr_cmd + i); + + while (i & 7) + ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ + + resources[0] = bo_dst; + resources[1] = bo_src; + resources[2] = bo_shader_ps; + resources[3] = bo_shader_vs; + resources[4] = bo_cmd; + r = amdgpu_bo_list_create(device_handle, 5, resources, NULL, &bo_list); + CU_ASSERT_EQUAL(r, 0); + + ib_info.ib_mc_address = mc_address_cmd; + ib_info.size = i; + ibs_request.ip_type = AMDGPU_HW_IP_GFX; + ibs_request.ring = ring; + ibs_request.resources = bo_list; + ibs_request.number_of_ibs = 1; + ibs_request.ibs = &ib_info; + ibs_request.fence_info.handle = NULL; + r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); + CU_ASSERT_EQUAL(r, 0); + + fence_status.ip_type = AMDGPU_HW_IP_GFX; + fence_status.ip_instance = 0; + fence_status.ring = ring; + fence_status.context = context_handle; + fence_status.fence = ibs_request.seq_no; + + /* wait for IB accomplished */ + r = amdgpu_cs_query_fence_status(&fence_status, + AMDGPU_TIMEOUT_INFINITE, + 0, &expired); + + r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); + + r = amdgpu_bo_list_destroy(bo_list); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_size); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_unmap_and_free(bo_src, va_src, mc_address_src, bo_size); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(bo_shader_ps, va_shader_ps, mc_address_shader_ps, bo_shader_ps_size); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_unmap_and_free(bo_shader_vs, va_shader_vs, mc_address_shader_vs, bo_shader_vs_size); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_cs_ctx_free(context_handle); + CU_ASSERT_EQUAL(r, 0); +} + static void amdgpu_gpu_reset_test(void) { int r; diff --git a/tests/amdgpu/cs_tests.c b/tests/amdgpu/cs_tests.c index 7ad0f0d..ae4f65f 100644 --- a/tests/amdgpu/cs_tests.c +++ b/tests/amdgpu/cs_tests.c @@ -358,6 +358,7 @@ static void amdgpu_cs_uvd_decode(void) bs_addr = fb_addr + 4*1024; dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024); + ctx_addr = 0; if (family_id >= AMDGPU_FAMILY_VI) { if ((family_id == AMDGPU_FAMILY_AI) || (chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A || diff --git a/tests/amdgpu/deadlock_tests.c b/tests/amdgpu/deadlock_tests.c index 91368c1..a18d578 100644 --- a/tests/amdgpu/deadlock_tests.c +++ b/tests/amdgpu/deadlock_tests.c @@ -24,7 +24,7 @@ #include #include #include -#ifdef HAVE_ALLOCA_H +#if HAVE_ALLOCA_H # include #endif @@ -114,6 +114,12 @@ static void amdgpu_deadlock_compute(void); static void amdgpu_illegal_reg_access(); static void amdgpu_illegal_mem_access(); static void amdgpu_deadlock_sdma(void); +static void amdgpu_dispatch_hang_gfx(void); +static void amdgpu_dispatch_hang_compute(void); +static void amdgpu_dispatch_hang_slow_gfx(void); +static void amdgpu_dispatch_hang_slow_compute(void); +static void amdgpu_draw_hang_gfx(void); +static void amdgpu_draw_hang_slow_gfx(void); CU_BOOL suite_deadlock_tests_enable(void) { @@ -178,6 +184,12 @@ CU_TestInfo deadlock_tests[] = { { "sdma ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_sdma }, { "illegal reg access test", amdgpu_illegal_reg_access }, { "illegal mem access test (set amdgpu.vm_fault_stop=2)", amdgpu_illegal_mem_access }, + { "gfx ring bad dispatch test (set amdgpu.lockup_timeout=50)", amdgpu_dispatch_hang_gfx }, + { "compute ring bad dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_compute }, + { "gfx ring bad slow dispatch test (set amdgpu.lockup_timeout=50)", amdgpu_dispatch_hang_slow_gfx }, + { "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_slow_compute }, + { "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_gfx }, + { "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_slow_gfx }, CU_TEST_INFO_NULL, }; @@ -478,3 +490,57 @@ static void amdgpu_illegal_mem_access() { bad_access_helper(0); } + +static void amdgpu_dispatch_hang_gfx(void) +{ + amdgpu_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_GFX); +} + +static void amdgpu_dispatch_hang_compute(void) +{ + amdgpu_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_COMPUTE); +} + +static void amdgpu_dispatch_hang_slow_gfx(void) +{ + amdgpu_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_GFX); +} + +static void amdgpu_dispatch_hang_slow_compute(void) +{ + amdgpu_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_COMPUTE); +} + +static void amdgpu_draw_hang_gfx(void) +{ + int r; + struct drm_amdgpu_info_hw_ip info; + uint32_t ring_id; + + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); + CU_ASSERT_EQUAL(r, 0); + if (!info.available_rings) + printf("SKIP ... as there's no graphic ring\n"); + + for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { + amdgpu_memcpy_draw_test(device_handle, ring_id, 0); + amdgpu_memcpy_draw_test(device_handle, ring_id, 1); + amdgpu_memcpy_draw_test(device_handle, ring_id, 0); + } +} + +static void amdgpu_draw_hang_slow_gfx(void) +{ + struct drm_amdgpu_info_hw_ip info; + uint32_t ring_id; + int r; + + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); + CU_ASSERT_EQUAL(r, 0); + + for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { + amdgpu_memcpy_draw_test(device_handle, ring_id, 0); + amdgpu_memcpy_draw_hang_slow_test(device_handle, ring_id); + amdgpu_memcpy_draw_test(device_handle, ring_id, 0); + } +} diff --git a/tests/amdgpu/ras_tests.c b/tests/amdgpu/ras_tests.c index c1c543c..810bf17 100644 --- a/tests/amdgpu/ras_tests.c +++ b/tests/amdgpu/ras_tests.c @@ -30,6 +30,9 @@ #include #include #include "xf86drm.h" +#include + +#define PATH_SIZE PATH_MAX #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -498,7 +501,7 @@ static int get_file_contents(char *file, char *buf, int size); static int amdgpu_ras_lookup_id(drmDevicePtr device) { - char path[1024]; + char path[PATH_SIZE]; char str[128]; drmPciBusInfo info; int i; @@ -507,7 +510,7 @@ static int amdgpu_ras_lookup_id(drmDevicePtr device) for (i = 0; i < MAX_CARDS_SUPPORTED; i++) { memset(str, 0, sizeof(str)); memset(&info, 0, sizeof(info)); - sprintf(path, "/sys/kernel/debug/dri/%d/name", i); + snprintf(path, PATH_SIZE, "/sys/kernel/debug/dri/%d/name", i); if (get_file_contents(path, str, sizeof(str)) <= 0) continue; @@ -522,146 +525,24 @@ static int amdgpu_ras_lookup_id(drmDevicePtr device) return -1; } -CU_BOOL suite_ras_tests_enable(void) -{ - amdgpu_device_handle device_handle; - uint32_t major_version; - uint32_t minor_version; - int i; - drmDevicePtr device; - - for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) { - if (amdgpu_device_initialize(drm_amdgpu[i], &major_version, - &minor_version, &device_handle)) - continue; - - if (drmGetDevice2(drm_amdgpu[i], - DRM_DEVICE_GET_PCI_REVISION, - &device)) - continue; - - if (device->bustype == DRM_BUS_PCI && - amdgpu_ras_lookup_capability(device_handle)) { - amdgpu_device_deinitialize(device_handle); - return CU_TRUE; - } - - if (amdgpu_device_deinitialize(device_handle)) - continue; - } - - return CU_FALSE; -} - -int suite_ras_tests_init(void) -{ - drmDevicePtr device; - amdgpu_device_handle device_handle; - uint32_t major_version; - uint32_t minor_version; - uint32_t capability; - struct ras_test_mask test_mask; - int id; - int i; - int r; - - for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) { - r = amdgpu_device_initialize(drm_amdgpu[i], &major_version, - &minor_version, &device_handle); - if (r) - continue; - - if (drmGetDevice2(drm_amdgpu[i], - DRM_DEVICE_GET_PCI_REVISION, - &device)) { - amdgpu_device_deinitialize(device_handle); - continue; - } - - if (device->bustype != DRM_BUS_PCI) { - amdgpu_device_deinitialize(device_handle); - continue; - } - - capability = amdgpu_ras_lookup_capability(device_handle); - if (capability == 0) { - amdgpu_device_deinitialize(device_handle); - continue; - - } - - id = amdgpu_ras_lookup_id(device); - if (id == -1) { - amdgpu_device_deinitialize(device_handle); - continue; - } - - test_mask = amdgpu_ras_get_test_mask(device); - - devices[devices_count++] = (struct amdgpu_ras_data) { - device_handle, id, capability, test_mask, - }; - } - - if (devices_count == 0) - return CUE_SINIT_FAILED; - - return CUE_SUCCESS; -} - -int suite_ras_tests_clean(void) -{ - int r; - int i; - int ret = CUE_SUCCESS; - - for (i = 0; i < devices_count; i++) { - r = amdgpu_device_deinitialize(devices[i].device_handle); - if (r) - ret = CUE_SCLEAN_FAILED; - } - return ret; -} - -static void amdgpu_ras_disable_test(void); -static void amdgpu_ras_enable_test(void); -static void amdgpu_ras_inject_test(void); -static void amdgpu_ras_query_test(void); -static void amdgpu_ras_basic_test(void); - -CU_TestInfo ras_tests[] = { - { "ras basic test", amdgpu_ras_basic_test }, - { "ras query test", amdgpu_ras_query_test }, - { "ras inject test", amdgpu_ras_inject_test }, - { "ras disable test", amdgpu_ras_disable_test }, -#if 0 - { "ras enable test", amdgpu_ras_enable_test }, -#endif - CU_TEST_INFO_NULL, -}; - //helpers static int test_card; -static char sysfs_path[1024]; -static char debugfs_path[1024]; +static char sysfs_path[PATH_SIZE]; +static char debugfs_path[PATH_SIZE]; static uint32_t ras_mask; static amdgpu_device_handle device_handle; -static int set_test_card(int card) +static void set_test_card(int card) { - int i; - test_card = card; - sprintf(sysfs_path, "/sys/class/drm/card%d/device/ras/", devices[card].id); - sprintf(debugfs_path, "/sys/kernel/debug/dri/%d/ras/", devices[card].id); + snprintf(sysfs_path, PATH_SIZE, "/sys/class/drm/card%d/device/ras/", devices[card].id); + snprintf(debugfs_path, PATH_SIZE, "/sys/kernel/debug/dri/%d/ras/", devices[card].id); ras_mask = devices[card].capability; device_handle = devices[card].device_handle; ras_block_mask_inject = devices[card].test_mask.inject_mask; ras_block_mask_query = devices[card].test_mask.query_mask; ras_block_mask_basic = devices[card].test_mask.basic_mask; - - return 0; } static const char *get_ras_sysfs_root(void) @@ -727,10 +608,11 @@ static int amdgpu_ras_is_feature_supported(enum amdgpu_ras_block block) static int amdgpu_ras_invoke(struct ras_debug_if *data) { - char path[1024]; + char path[PATH_SIZE]; int ret; - sprintf(path, "%s%s", get_ras_debugfs_root(), "ras_ctrl"); + snprintf(path, sizeof(path), "%s", get_ras_debugfs_root()); + strncat(path, "ras_ctrl", sizeof(path) - strlen(path)); ret = set_file_contents(path, (char *)data, sizeof(*data)) - sizeof(*data); @@ -741,15 +623,16 @@ static int amdgpu_ras_query_err_count(enum amdgpu_ras_block block, unsigned long *ue, unsigned long *ce) { char buf[64]; - char name[1024]; - int ret; + char name[PATH_SIZE]; *ue = *ce = 0; if (amdgpu_ras_is_feature_supported(block) <= 0) return -1; - sprintf(name, "%s%s%s", get_ras_sysfs_root(), ras_block_str(block), "_err_count"); + snprintf(name, sizeof(name), "%s", get_ras_sysfs_root()); + strncat(name, ras_block_str(block), sizeof(name) - strlen(name)); + strncat(name, "_err_count", sizeof(name) - strlen(name)); if (is_file_ok(name, O_RDONLY)) return 0; @@ -779,7 +662,7 @@ static int amdgpu_ras_inject(enum amdgpu_ras_block block, inject->head.block = block; inject->head.type = type; inject->head.sub_block_index = sub_block; - strncpy(inject->head.name, ras_block_str(block), 32); + strncpy(inject->head.name, ras_block_str(block), sizeof(inject->head.name)-1); inject->address = address; inject->value = value; @@ -956,13 +839,11 @@ static void amdgpu_ras_query_test(void) static void amdgpu_ras_basic_test(void) { - unsigned long ue, ce; - char name[1024]; int ret; int i; int j; uint32_t features; - char path[1024]; + char path[PATH_SIZE]; ret = is_file_ok("/sys/module/amdgpu/parameters/ras_mask", O_RDONLY); CU_ASSERT_EQUAL(ret, 0); @@ -974,11 +855,15 @@ static void amdgpu_ras_basic_test(void) sizeof(features), &features); CU_ASSERT_EQUAL(ret, 0); - sprintf(path, "%s%s", get_ras_debugfs_root(), "ras_ctrl"); + snprintf(path, sizeof(path), "%s", get_ras_debugfs_root()); + strncat(path, "ras_ctrl", sizeof(path) - strlen(path)); + ret = is_file_ok(path, O_WRONLY); CU_ASSERT_EQUAL(ret, 0); - sprintf(path, "%s%s", get_ras_sysfs_root(), "features"); + snprintf(path, sizeof(path), "%s", get_ras_sysfs_root()); + strncat(path, "features", sizeof(path) - strlen(path)); + ret = is_file_ok(path, O_RDONLY); CU_ASSERT_EQUAL(ret, 0); @@ -990,13 +875,129 @@ static void amdgpu_ras_basic_test(void) if (!((1 << j) & ras_block_mask_basic)) continue; - sprintf(path, "%s%s%s", get_ras_sysfs_root(), ras_block_str(j), "_err_count"); + snprintf(path, sizeof(path), "%s", get_ras_sysfs_root()); + strncat(path, ras_block_str(j), sizeof(path) - strlen(path)); + strncat(path, "_err_count", sizeof(path) - strlen(path)); + ret = is_file_ok(path, O_RDONLY); CU_ASSERT_EQUAL(ret, 0); - sprintf(path, "%s%s%s", get_ras_debugfs_root(), ras_block_str(j), "_err_inject"); + snprintf(path, sizeof(path), "%s", get_ras_debugfs_root()); + strncat(path, ras_block_str(j), sizeof(path) - strlen(path)); + strncat(path, "_err_inject", sizeof(path) - strlen(path)); + ret = is_file_ok(path, O_WRONLY); CU_ASSERT_EQUAL(ret, 0); } } } + +CU_TestInfo ras_tests[] = { + { "ras basic test", amdgpu_ras_basic_test }, + { "ras query test", amdgpu_ras_query_test }, + { "ras inject test", amdgpu_ras_inject_test }, + { "ras disable test", amdgpu_ras_disable_test }, + { "ras enable test", amdgpu_ras_enable_test }, + CU_TEST_INFO_NULL, +}; + +CU_BOOL suite_ras_tests_enable(void) +{ + amdgpu_device_handle device_handle; + uint32_t major_version; + uint32_t minor_version; + int i; + drmDevicePtr device; + + for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) { + if (amdgpu_device_initialize(drm_amdgpu[i], &major_version, + &minor_version, &device_handle)) + continue; + + if (drmGetDevice2(drm_amdgpu[i], + DRM_DEVICE_GET_PCI_REVISION, + &device)) + continue; + + if (device->bustype == DRM_BUS_PCI && + amdgpu_ras_lookup_capability(device_handle)) { + amdgpu_device_deinitialize(device_handle); + return CU_TRUE; + } + + if (amdgpu_device_deinitialize(device_handle)) + continue; + } + + return CU_FALSE; +} + +int suite_ras_tests_init(void) +{ + drmDevicePtr device; + amdgpu_device_handle device_handle; + uint32_t major_version; + uint32_t minor_version; + uint32_t capability; + struct ras_test_mask test_mask; + int id; + int i; + int r; + + for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) { + r = amdgpu_device_initialize(drm_amdgpu[i], &major_version, + &minor_version, &device_handle); + if (r) + continue; + + if (drmGetDevice2(drm_amdgpu[i], + DRM_DEVICE_GET_PCI_REVISION, + &device)) { + amdgpu_device_deinitialize(device_handle); + continue; + } + + if (device->bustype != DRM_BUS_PCI) { + amdgpu_device_deinitialize(device_handle); + continue; + } + + capability = amdgpu_ras_lookup_capability(device_handle); + if (capability == 0) { + amdgpu_device_deinitialize(device_handle); + continue; + + } + + id = amdgpu_ras_lookup_id(device); + if (id == -1) { + amdgpu_device_deinitialize(device_handle); + continue; + } + + test_mask = amdgpu_ras_get_test_mask(device); + + devices[devices_count++] = (struct amdgpu_ras_data) { + device_handle, id, capability, test_mask, + }; + } + + if (devices_count == 0) + return CUE_SINIT_FAILED; + + return CUE_SUCCESS; +} + +int suite_ras_tests_clean(void) +{ + int r; + int i; + int ret = CUE_SUCCESS; + + for (i = 0; i < devices_count; i++) { + r = amdgpu_device_deinitialize(devices[i].device_handle); + if (r) + ret = CUE_SCLEAN_FAILED; + } + return ret; +} diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c index 869ed88..3a7b38e 100644 --- a/tests/amdgpu/syncobj_tests.c +++ b/tests/amdgpu/syncobj_tests.c @@ -96,7 +96,7 @@ static int syncobj_command_submission_helper(uint32_t syncobj_handle, bool struct amdgpu_cs_fence fence_status; amdgpu_bo_list_handle bo_list; amdgpu_va_handle va_handle; - uint32_t expired, flags; + uint32_t expired; int i, r; uint64_t seq_no; static uint32_t *ptr; diff --git a/tests/kms/kms-steal-crtc.c b/tests/kms/kms-steal-crtc.c index cd40758..4d884c0 100644 --- a/tests/kms/kms-steal-crtc.c +++ b/tests/kms/kms-steal-crtc.c @@ -28,7 +28,7 @@ #include #include #include -#ifdef HAVE_SYS_SELECT_H +#if HAVE_SYS_SELECT_H #include #endif diff --git a/tests/kms/kms-universal-planes.c b/tests/kms/kms-universal-planes.c index 2163c98..1d79388 100644 --- a/tests/kms/kms-universal-planes.c +++ b/tests/kms/kms-universal-planes.c @@ -28,7 +28,7 @@ #include #include #include -#ifdef HAVE_SYS_SELECT_H +#if HAVE_SYS_SELECT_H #include #endif diff --git a/tests/kms/libkms-test-screen.c b/tests/kms/libkms-test-screen.c index bbe972a..d00ae54 100644 --- a/tests/kms/libkms-test-screen.c +++ b/tests/kms/libkms-test-screen.c @@ -42,7 +42,9 @@ static void kms_screen_probe(struct kms_screen *screen) else screen->connected = false; - memcpy(&screen->mode, &con->modes[0], sizeof(drmModeModeInfo)); + if (con->modes) + memcpy(&screen->mode, &con->modes[0], sizeof(drmModeModeInfo)); + screen->width = screen->mode.hdisplay; screen->height = screen->mode.vdisplay; diff --git a/tests/meson.build b/tests/meson.build index 6c8ddd9..5aab5a0 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -64,14 +64,6 @@ hash = executable( c_args : libdrm_c_args, ) -random = executable( - 'random', - files('random.c'), - include_directories : [inc_root, inc_drm], - link_with : libdrm, - c_args : libdrm_c_args, -) - drmdevice = executable( 'drmdevice', files('drmdevice.c'), @@ -80,7 +72,6 @@ drmdevice = executable( c_args : libdrm_c_args, ) -test('random', random, timeout : 240) test('hash', hash) test('drmsl', drmsl) test('drmdevice', drmdevice) diff --git a/tests/modetest/Android.mk b/tests/modetest/Android.mk new file mode 100644 index 0000000..c1a71fd --- /dev/null +++ b/tests/modetest/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_SRC_FILES := $(MODETEST_FILES) + +LOCAL_MODULE := modetest + +LOCAL_SHARED_LIBRARIES := libdrm +LOCAL_STATIC_LIBRARIES := libdrm_util + +include $(LIBDRM_COMMON_MK) +include $(BUILD_EXECUTABLE) diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index e66be66..b907ab3 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -51,9 +51,10 @@ #include #include #include -#ifdef HAVE_SYS_SELECT_H +#if HAVE_SYS_SELECT_H #include #endif +#include #include "xf86drm.h" #include "xf86drmMode.h" @@ -132,6 +133,12 @@ static inline int64_t U642I64(uint64_t val) return (int64_t)*((int64_t *)&val); } +static float mode_vrefresh(drmModeModeInfo *mode) +{ + return mode->clock * 1000.00 + / (mode->htotal * mode->vtotal); +} + #define bit_name_fn(res) \ const char * res##_str(int type) { \ unsigned int i; \ @@ -207,11 +214,12 @@ static void dump_encoders(struct device *dev) printf("\n"); } -static void dump_mode(drmModeModeInfo *mode) +static void dump_mode(drmModeModeInfo *mode, int index) { - printf(" %s %d %d %d %d %d %d %d %d %d %d", + printf(" #%i %s %.2f %d %d %d %d %d %d %d %d %d", + index, mode->name, - mode->vrefresh, + mode_vrefresh(mode), mode->hdisplay, mode->hsync_start, mode->hsync_end, @@ -446,10 +454,10 @@ static void dump_connectors(struct device *dev) if (connector->count_modes) { printf(" modes:\n"); - printf("\tname refresh (Hz) hdisp hss hse htot vdisp " + printf("\tindex name refresh (Hz) hdisp hss hse htot vdisp " "vss vse vtot)\n"); for (j = 0; j < connector->count_modes; j++) - dump_mode(&connector->modes[j]); + dump_mode(&connector->modes[j], j); } if (_connector->props) { @@ -481,7 +489,7 @@ static void dump_crtcs(struct device *dev) crtc->buffer_id, crtc->x, crtc->y, crtc->width, crtc->height); - dump_mode(&crtc->mode); + dump_mode(&crtc->mode, 0); if (_crtc->props) { printf(" props:\n"); @@ -795,7 +803,7 @@ struct pipe_arg { uint32_t crtc_id; char mode_str[64]; char format_str[5]; - unsigned int vrefresh; + float vrefresh; unsigned int fourcc; drmModeModeInfo *mode; struct crtc *crtc; @@ -822,7 +830,7 @@ struct plane_arg { static drmModeModeInfo * connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str, - const unsigned int vrefresh) + const float vrefresh) { drmModeConnector *connector; drmModeModeInfo *mode; @@ -832,16 +840,27 @@ connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str, if (!connector || !connector->count_modes) return NULL; + /* Pick by Index */ + if (mode_str[0] == '#') { + int index = atoi(mode_str + 1); + + if (index >= connector->count_modes || index < 0) + return NULL; + return &connector->modes[index]; + } + + /* Pick by Name */ for (i = 0; i < connector->count_modes; i++) { mode = &connector->modes[i]; if (!strcmp(mode->name, mode_str)) { - /* If the vertical refresh frequency is not specified then return the - * first mode that match with the name. Else, return the mode that match - * the name and the specified vertical refresh frequency. + /* If the vertical refresh frequency is not specified + * then return the first mode that match with the name. + * Else, return the mode that match the name and + * the specified vertical refresh frequency. */ if (vrefresh == 0) return mode; - else if (mode->vrefresh == vrefresh) + else if (fabs(mode_vrefresh(mode) - vrefresh) < 0.005) return mode; } } @@ -907,7 +926,13 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe) mode = connector_find_mode(dev, pipe->con_ids[i], pipe->mode_str, pipe->vrefresh); if (mode == NULL) { - fprintf(stderr, + if (pipe->vrefresh) + fprintf(stderr, + "failed to find mode " + "\"%s-%.2fHz\" for connector %s\n", + pipe->mode_str, pipe->vrefresh, pipe->cons[i]); + else + fprintf(stderr, "failed to find mode \"%s\" for connector %s\n", pipe->mode_str, pipe->cons[i]); return -EINVAL; @@ -1393,8 +1418,8 @@ static void atomic_set_mode(struct device *dev, struct pipe_arg *pipes, unsigned if (pipe->mode == NULL) continue; - printf("setting mode %s-%dHz on connectors ", - pipe->mode_str, pipe->mode->vrefresh); + printf("setting mode %s-%.2fHz on connectors ", + pipe->mode->name, mode_vrefresh(pipe->mode)); for (j = 0; j < pipe->num_cons; ++j) { printf("%s, ", pipe->cons[j]); add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc->crtc->crtc_id); @@ -1476,8 +1501,9 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co if (pipe->mode == NULL) continue; - printf("setting mode %s-%dHz@%s on connectors ", - pipe->mode_str, pipe->mode->vrefresh, pipe->format_str); + printf("setting mode %s-%.2fHz@%s on connectors ", + pipe->mode->name, mode_vrefresh(pipe->mode), + pipe->format_str); for (j = 0; j < pipe->num_cons; ++j) printf("%s, ", pipe->cons[j]); printf("crtc %d\n", pipe->crtc->crtc->crtc_id); @@ -1695,6 +1721,8 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg) return -1; /* Parse the remaining parameters. */ + if (!endp) + return -1; if (*endp == '@') { arg = endp + 1; pipe->crtc_id = strtoul(arg, &endp, 10); @@ -1713,7 +1741,7 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg) pipe->mode_str[len] = '\0'; if (*p == '-') { - pipe->vrefresh = strtoul(p + 1, &endp, 10); + pipe->vrefresh = strtof(p + 1, &endp); p = endp; } @@ -1821,7 +1849,7 @@ static void usage(char *name) fprintf(stderr, "\n Test options:\n\n"); fprintf(stderr, "\t-P @:x[++][*][@]\tset a plane\n"); - fprintf(stderr, "\t-s [,][@]:[-][@]\tset a mode\n"); + fprintf(stderr, "\t-s [,][@]:[#][-][@]\tset a mode\n"); fprintf(stderr, "\t-C\ttest hw cursor\n"); fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); fprintf(stderr, "\t-w ::\tset property\n"); diff --git a/tests/nouveau/.gitignore b/tests/nouveau/.gitignore new file mode 100644 index 0000000..837bfb9 --- /dev/null +++ b/tests/nouveau/.gitignore @@ -0,0 +1 @@ +threaded diff --git a/tests/nouveau/threaded.c b/tests/nouveau/threaded.c index 3669bcd..e1c27c0 100644 --- a/tests/nouveau/threaded.c +++ b/tests/nouveau/threaded.c @@ -36,7 +36,11 @@ static int failed; static int import_fd; +#ifdef __GLIBC__ int ioctl(int fd, unsigned long request, ...) +#else +int ioctl(int fd, int request, ...) +#endif { va_list va; int ret; diff --git a/tests/proptest/Android.mk b/tests/proptest/Android.mk new file mode 100644 index 0000000..91a590f --- /dev/null +++ b/tests/proptest/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_SRC_FILES := $(PROPTEST_FILES) + +LOCAL_MODULE := proptest + +LOCAL_SHARED_LIBRARIES := libdrm +LOCAL_STATIC_LIBRARIES := libdrm_util + +include $(LIBDRM_COMMON_MK) +include $(BUILD_EXECUTABLE) diff --git a/tests/tegra/.gitignore b/tests/tegra/.gitignore new file mode 100644 index 0000000..5c5216c --- /dev/null +++ b/tests/tegra/.gitignore @@ -0,0 +1 @@ +openclose diff --git a/tests/ttmtest/AUTHORS b/tests/ttmtest/AUTHORS new file mode 100644 index 0000000..fa4a089 --- /dev/null +++ b/tests/ttmtest/AUTHORS @@ -0,0 +1 @@ +Thomas Hellstr�m and others. diff --git a/tests/ttmtest/ChangeLog b/tests/ttmtest/ChangeLog new file mode 100644 index 0000000..4588c8d --- /dev/null +++ b/tests/ttmtest/ChangeLog @@ -0,0 +1,23 @@ +2006-01-24 Thomas Hellstr�m + + * configure.ac: + * src/ttmtest.c: + + Fixed include path. + +2006-01-24 Thomas Hellstr�m + + * AUTHORS: + * Makefile.am: + * configure.ac: + * reconf: + * src/Makefile.am: + * src/ttmtest.c: (fastrdtsc), (time_diff), (releaseContext), + (testAGP), (main): + * src/xf86dri.c: (uniDRIDestroyContext), (uniDRICreateDrawable), + (uniDRIDestroyDrawable), (uniDRIGetDrawableInfo): + * src/xf86dri.h: + * src/xf86dristr.h: + + Initial import of the ttmtest utility. + \ No newline at end of file diff --git a/tests/ttmtest/Makefile.am b/tests/ttmtest/Makefile.am new file mode 100644 index 0000000..af437a6 --- /dev/null +++ b/tests/ttmtest/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src diff --git a/tests/ttmtest/NEWS b/tests/ttmtest/NEWS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/ttmtest/NEWS diff --git a/tests/ttmtest/README b/tests/ttmtest/README new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/ttmtest/README diff --git a/tests/ttmtest/configure.ac b/tests/ttmtest/configure.ac new file mode 100644 index 0000000..c41e91a --- /dev/null +++ b/tests/ttmtest/configure.ac @@ -0,0 +1,33 @@ +AC_INIT +AC_PROG_CC +AC_PATH_X +if test "x$no_x" != "xyes"; then + savecpp="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -I$x_includes" + AC_CHECK_HEADER($x_includes/X11/Xlib.h,,\ + [AC_MSG_ERROR(Could not find X installation.)]) + CPPFLAGS="$savecpp" + MDRIINC="-I$x_includes" + LIBS="-L$x_libraries $LIBS" +else + AC_MSG_ERROR(Could not find X installation. Aborting.) +fi +AC_ARG_WITH(libdrm, + AC_HELP_STRING([--with-libdrm=DIR], + [Installation prefix of libdrm [[default=/usr]]]), + [libdrmpref="$withval"], + [libdrmpref="/usr"]) +savecpp="$CPPFLAGS" +MDRIINC="-I$libdrmpref/include -I$libdrmpref/include/drm -I$x_includes" +CPPFLAGS="$CPPFLAGS $MDRIINC" +AC_CHECK_HEADER(xf86drm.h,,\ + [AC_MSG_ERROR(Could not find libdrm installation. Use --with-libdrm=)]) +AC_CHECK_HEADER(drm.h,,\ + [AC_MSG_ERROR(Could not find libdrm installation. Use --with-libdrm=)]) +CPPFLAGS="$savecpp" +LIBS="-L$libdrmpref/lib64 -L$libdrmpref/lib $LIBS" +AC_SUBST(MDRIINC) +AC_SYS_LARGEFILE +AM_INIT_AUTOMAKE(minidri,0.1.0) +AM_CONFIG_HEADER(config.h) +AC_OUTPUT([Makefile src/Makefile]) diff --git a/tests/ttmtest/reconf b/tests/ttmtest/reconf new file mode 100755 index 0000000..e64d00a --- /dev/null +++ b/tests/ttmtest/reconf @@ -0,0 +1,2 @@ +#!/bin/sh +autoreconf -v --install || exit 1 \ No newline at end of file diff --git a/tests/ttmtest/src/Makefile.am b/tests/ttmtest/src/Makefile.am new file mode 100644 index 0000000..b7ee829 --- /dev/null +++ b/tests/ttmtest/src/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = @MDRIINC@ +bin_PROGRAMS = ttmtest +ttmtest_SOURCES = \ + ttmtest.c \ + xf86dri.c \ + xf86dri.h \ + xf86dristr.h +ttmtest_LDADD = -ldrm -lXext -lX11 diff --git a/tests/ttmtest/src/ttmtest.c b/tests/ttmtest/src/ttmtest.c new file mode 100644 index 0000000..36df242 --- /dev/null +++ b/tests/ttmtest/src/ttmtest.c @@ -0,0 +1,430 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstr�m + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include "xf86dri.h" +#include "xf86drm.h" +#include "stdio.h" +#include "sys/types.h" +#include +#include +#include +#include +#include "sys/mman.h" + +typedef struct +{ + enum + { + haveNothing, + haveDisplay, + haveConnection, + haveDriverName, + haveDeviceInfo, + haveDRM, + haveContext + } + state; + + Display *display; + int screen; + drm_handle_t sAreaOffset; + char *curBusID; + char *driverName; + int drmFD; + XVisualInfo visualInfo; + XID id; + drm_context_t hwContext; + void *driPriv; + int driPrivSize; + int fbSize; + int fbOrigin; + int fbStride; + drm_handle_t fbHandle; + int ddxDriverMajor; + int ddxDriverMinor; + int ddxDriverPatch; +} TinyDRIContext; + +#ifndef __x86_64__ +static unsigned +fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" + "pushl %%ebx\n\t" + "cpuid\n\t" ".byte 0x0f, 0x31\n\t" "popl %%ebx\n":"=a" (eax) + :"0"(0) + :"ecx", "edx", "cc"); + + return eax; +} +#else +static unsigned +fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax) + :"0"(0) + :"ecx", "edx", "ebx", "cc"); + + return eax; +} +#endif + +void +bmError(int val, const char *file, const char *function, int line) +{ + fprintf(stderr, "Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); + abort(); +} + +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + +static unsigned +time_diff(unsigned t, unsigned t2) +{ + return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1)); +} + +static int +releaseContext(TinyDRIContext * ctx) +{ + switch (ctx->state) { + case haveContext: + uniDRIDestroyContext(ctx->display, ctx->screen, ctx->id); + case haveDRM: + drmClose(ctx->drmFD); + case haveDeviceInfo: + XFree(ctx->driPriv); + case haveDriverName: + XFree(ctx->driverName); + case haveConnection: + XFree(ctx->curBusID); + uniDRICloseConnection(ctx->display, ctx->screen); + case haveDisplay: + XCloseDisplay(ctx->display); + default: + break; + } + return -1; +} + +static void +readBuf(void *buf, unsigned long size) +{ + volatile unsigned *buf32 = (unsigned *)buf; + unsigned *end = (unsigned *)buf32 + size / sizeof(*buf32); + + while (buf32 < end) { + (void)*buf32++; + } +} + +static int +benchmarkBuffer(TinyDRIContext * ctx, unsigned long size, + unsigned long *ticks) +{ + unsigned long curTime, oldTime; + int ret; + drmBO buf; + void *virtual; + + /* + * Test system memory objects. + */ + oldTime = fastrdtsc(); + BM_CKFATAL(drmBOCreate(ctx->drmFD, size, 0, NULL, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_LOCAL, 0, &buf)); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + BM_CKFATAL(drmBOMap(ctx->drmFD, &buf, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual)); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + memset(virtual, 0xF0, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + memset(virtual, 0x0F, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + readBuf(virtual, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + BM_CKFATAL(drmBOUnmap(ctx->drmFD, &buf)); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + /* + * Test TT bound buffer objects. + */ + + oldTime = fastrdtsc(); + BM_CKFATAL(drmBOSetStatus(ctx->drmFD, &buf, + DRM_BO_FLAG_MEM_TT, + DRM_BO_MASK_MEM, + 0,0,0)); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + BM_CKFATAL(drmBOMap(ctx->drmFD, &buf, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual)); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + memset(virtual, 0xF0, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + memset(virtual, 0x0F, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + readBuf(virtual, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + BM_CKFATAL(drmBOUnmap(ctx->drmFD, &buf)); + + oldTime = fastrdtsc(); + BM_CKFATAL(drmBOSetStatus(ctx->drmFD, &buf, + DRM_BO_FLAG_MEM_LOCAL, DRM_BO_MASK_MEM, 0, 0,0)); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + /* + * Test cached buffers objects. + */ + + oldTime = fastrdtsc(); + ret = drmBOSetStatus(ctx->drmFD, &buf, + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_CACHED | + DRM_BO_FLAG_FORCE_CACHING, + DRM_BO_MASK_MEMTYPE | + DRM_BO_FLAG_FORCE_CACHING, + 0, 0, 0); + curTime = fastrdtsc(); + + if (ret) { + printf("Couldn't bind cached. Probably no support\n"); + BM_CKFATAL(drmBOUnreference(ctx->drmFD, &buf)); + return 1; + } + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + BM_CKFATAL(drmBOMap(ctx->drmFD, &buf, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual)); + + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + memset(virtual, 0xF0, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + memset(virtual, 0x0F, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + oldTime = fastrdtsc(); + readBuf(virtual, buf.size); + curTime = fastrdtsc(); + *ticks++ = time_diff(oldTime, curTime); + + BM_CKFATAL(drmBOUnmap(ctx->drmFD, &buf)); + BM_CKFATAL(drmBOUnreference(ctx->drmFD, &buf)); + + return 0; +} + +static void +testAGP(TinyDRIContext * ctx) +{ + unsigned long ticks[128], *pTicks; + unsigned long size = 8 * 1024; + int ret; + + ret = benchmarkBuffer(ctx, size, ticks); + if (ret < 0) { + fprintf(stderr, "Buffer error %s\n", strerror(-ret)); + return; + } + pTicks = ticks; + + printf("Buffer size %d bytes\n", size); + printf("System memory timings ********************************\n"); + printf("Creation took %12lu ticks\n", *pTicks++); + printf("Mapping took %12lu ticks\n", *pTicks++); + printf("Writing took %12lu ticks\n", *pTicks++); + printf("Writing Again took %12lu ticks\n", *pTicks++); + printf("Reading took %12lu ticks\n", *pTicks++); + printf("Unmapping took %12lu ticks\n", *pTicks++); + + printf("\nTT Memory timings ************************************\n"); + printf("Moving to TT took %12lu ticks\n", *pTicks++); + printf("Mapping in TT took %12lu ticks\n", *pTicks++); + printf("Writing to TT took %12lu ticks\n", *pTicks++); + printf("Writing again to TT took %12lu ticks\n", *pTicks++); + printf("Reading from TT took %12lu ticks\n", *pTicks++); + printf("Moving to system took %12lu ticks\n", *pTicks++); + + if (ret == 1) + return; + + printf("\nCached TT Memory timings *****************************\n"); + printf("Moving to CTT took %12lu ticks\n", *pTicks++); + printf("Mapping in CTT took %12lu ticks\n", *pTicks++); + printf("Writing to CTT took %12lu ticks\n", *pTicks++); + printf("Re-writing to CTT took %12lu ticks\n", *pTicks++); + printf("Reading from CTT took %12lu ticks\n", *pTicks++); + printf("\n\n"); +} + +int +main() +{ + int ret, screen, isCapable; + char *displayName = ":0"; + TinyDRIContext ctx; + unsigned magic; + + ctx.screen = 0; + ctx.state = haveNothing; + ctx.display = XOpenDisplay(displayName); + if (!ctx.display) { + fprintf(stderr, "Could not open display\n"); + return releaseContext(&ctx); + } + ctx.state = haveDisplay; + + ret = + uniDRIQueryDirectRenderingCapable(ctx.display, ctx.screen, + &isCapable); + if (!ret || !isCapable) { + fprintf(stderr, "No DRI on this display:sceen\n"); + return releaseContext(&ctx); + } + + if (!uniDRIOpenConnection(ctx.display, ctx.screen, &ctx.sAreaOffset, + &ctx.curBusID)) { + fprintf(stderr, "Could not open DRI connection.\n"); + return releaseContext(&ctx); + } + ctx.state = haveConnection; + + if (!uniDRIGetClientDriverName(ctx.display, ctx.screen, + &ctx.ddxDriverMajor, &ctx.ddxDriverMinor, + &ctx.ddxDriverPatch, &ctx.driverName)) { + fprintf(stderr, "Could not get DRI driver name.\n"); + return releaseContext(&ctx); + } + ctx.state = haveDriverName; + + if (!uniDRIGetDeviceInfo(ctx.display, ctx.screen, + &ctx.fbHandle, &ctx.fbOrigin, &ctx.fbSize, + &ctx.fbStride, &ctx.driPrivSize, &ctx.driPriv)) { + fprintf(stderr, "Could not get DRI device info.\n"); + return releaseContext(&ctx); + } + ctx.state = haveDriverName; + + if ((ctx.drmFD = drmOpen(NULL, ctx.curBusID)) < 0) { + perror("DRM Device could not be opened"); + return releaseContext(&ctx); + } + ctx.state = haveDRM; + + drmGetMagic(ctx.drmFD, &magic); + if (!uniDRIAuthConnection(ctx.display, ctx.screen, magic)) { + fprintf(stderr, "Could not get X server to authenticate us.\n"); + return releaseContext(&ctx); + } + + ret = XMatchVisualInfo(ctx.display, ctx.screen, 24, TrueColor, + &ctx.visualInfo); + if (!ret) { + ret = XMatchVisualInfo(ctx.display, ctx.screen, 16, TrueColor, + &ctx.visualInfo); + if (!ret) { + fprintf(stderr, "Could not find a matching visual.\n"); + return releaseContext(&ctx); + } + } + + if (!uniDRICreateContext(ctx.display, ctx.screen, ctx.visualInfo.visual, + &ctx.id, &ctx.hwContext)) { + fprintf(stderr, "Could not create DRI context.\n"); + return releaseContext(&ctx); + } + ctx.state = haveContext; + + testAGP(&ctx); + + releaseContext(&ctx); + printf("Terminating normally\n"); + return 0; +} diff --git a/tests/ttmtest/src/xf86dri.c b/tests/ttmtest/src/xf86dri.c new file mode 100644 index 0000000..e6e0b89 --- /dev/null +++ b/tests/ttmtest/src/xf86dri.c @@ -0,0 +1,603 @@ +/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Faith + * + */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include "xf86dristr.h" + +static XExtensionInfo _xf86dri_info_data; +static XExtensionInfo *xf86dri_info = &_xf86dri_info_data; +static char xf86dri_extension_name[] = XF86DRINAME; + +#define uniDRICheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xf86dri_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int close_display(Display * dpy, XExtCodes * extCodes); +static /* const */ XExtensionHooks xf86dri_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static +XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info, + xf86dri_extension_name, &xf86dri_extension_hooks, 0, NULL) + + static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info) + +/***************************************************************************** + * * + * public XFree86-DRI Extension routines * + * * + *****************************************************************************/ +#if 0 +#include +#define TRACE(msg) fprintf(stderr,"uniDRI%s\n", msg); +#else +#define TRACE(msg) +#endif + Bool uniDRIQueryExtension(dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display(dpy); + + TRACE("QueryExtension..."); + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + TRACE("QueryExtension... return True"); + return True; + } else { + TRACE("QueryExtension... return False"); + return False; + } +} + +Bool +uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) + Display *dpy; + int *majorVersion; + int *minorVersion; + int *patchVersion; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIQueryVersionReply rep; + xXF86DRIQueryVersionReq *req; + + TRACE("QueryVersion..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryVersion; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return False"); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + *patchVersion = rep.patchVersion; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return True"); + return True; +} + +Bool +uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable) + Display *dpy; + int screen; + Bool *isCapable; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIQueryDirectRenderingCapableReply rep; + xXF86DRIQueryDirectRenderingCapableReq *req; + + TRACE("QueryDirectRenderingCapable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryDirectRenderingCapable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryDirectRenderingCapable; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return False"); + return False; + } + *isCapable = rep.isCapable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return True"); + return True; +} + +Bool +uniDRIOpenConnection(dpy, screen, hSAREA, busIdString) + Display *dpy; + int screen; + drm_handle_t *hSAREA; + char **busIdString; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIOpenConnectionReply rep; + xXF86DRIOpenConnectionReq *req; + + TRACE("OpenConnection..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIOpenConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIOpenConnection; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + + *hSAREA = rep.hSAREALow; +#ifdef LONG64 + if (sizeof(drm_handle_t) == 8) { + *hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32; + } +#endif + if (rep.length) { + if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { + _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + _XReadPad(dpy, *busIdString, rep.busIdStringLength); + } else { + *busIdString = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return True"); + return True; +} + +Bool +uniDRIAuthConnection(dpy, screen, magic) + Display *dpy; + int screen; + drm_magic_t magic; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIAuthConnectionReq *req; + xXF86DRIAuthConnectionReply rep; + + TRACE("AuthConnection..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIAuthConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIAuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return False"); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return True"); + return True; +} + +Bool +uniDRICloseConnection(dpy, screen) + Display *dpy; + int screen; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICloseConnectionReq *req; + + TRACE("CloseConnection..."); + + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICloseConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICloseConnection; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CloseConnection... return True"); + return True; +} + +Bool +uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, + ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName) + Display *dpy; + int screen; + int *ddxDriverMajorVersion; + int *ddxDriverMinorVersion; + int *ddxDriverPatchVersion; + char **clientDriverName; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetClientDriverNameReply rep; + xXF86DRIGetClientDriverNameReq *req; + + TRACE("GetClientDriverName..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetClientDriverName, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetClientDriverName; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + + *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; + *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; + *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; + + if (rep.length) { + if (!(*clientDriverName = + (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { + _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); + } else { + *clientDriverName = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return True"); + return True; +} + +Bool +uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext) + Display *dpy; + int screen; + int configID; + XID *context; + drm_context_t *hHWContext; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICreateContextReply rep; + xXF86DRICreateContextReq *req; + + TRACE("CreateContext..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateContext; + req->visual = configID; + req->screen = screen; + *context = XAllocID(dpy); + req->context = *context; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return False"); + return False; + } + *hHWContext = rep.hHWContext; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return True"); + return True; +} + +Bool +uniDRICreateContext(dpy, screen, visual, context, hHWContext) + Display *dpy; + int screen; + Visual *visual; + XID *context; + drm_context_t *hHWContext; +{ + return uniDRICreateContextWithConfig(dpy, screen, visual->visualid, + context, hHWContext); +} + +Bool +uniDRIDestroyContext(Display * ndpy, int screen, XID context) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIDestroyContextReq *req; + + TRACE("DestroyContext..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyContext; + req->screen = screen; + req->context = context; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyContext... return True"); + return True; +} + +Bool +uniDRICreateDrawable(Display * ndpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICreateDrawableReply rep; + xXF86DRICreateDrawableReq *req; + + TRACE("CreateDrawable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateDrawable; + req->screen = screen; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return False"); + return False; + } + *hHWDrawable = rep.hHWDrawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return True"); + return True; +} + +Bool +uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIDestroyDrawableReq *req; + + TRACE("DestroyDrawable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyDrawable; + req->screen = screen; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyDrawable... return True"); + return True; +} + +Bool +uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t ** pBackClipRects) +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetDrawableInfoReply rep; + xXF86DRIGetDrawableInfoReq *req; + int total_rects; + + TRACE("GetDrawableInfo..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDrawableInfo; + req->screen = screen; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } + *index = rep.drawableTableIndex; + *stamp = rep.drawableTableStamp; + *X = (int)rep.drawableX; + *Y = (int)rep.drawableY; + *W = (int)rep.drawableWidth; + *H = (int)rep.drawableHeight; + *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + +#if 0 + /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks + * backwards compatibility (Because of the >> 2 shift) but the fix + * enables multi-threaded apps to work. + */ + if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(drm_clip_rect_t)) + + 3) & ~3) >> 2)) { + _XEatData(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } +#endif + + if (*numClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numClipRects); + + *pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1); + if (*pClipRects) + _XRead(dpy, (char *)*pClipRects, len); + } else { + *pClipRects = NULL; + } + + if (*numBackClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); + + *pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1); + if (*pBackClipRects) + _XRead(dpy, (char *)*pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return True"); + return True; +} + +Bool +uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer, + fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) + Display *dpy; + int screen; + drm_handle_t *hFrameBuffer; + int *fbOrigin; + int *fbSize; + int *fbStride; + int *devPrivateSize; + void **pDevPrivate; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetDeviceInfoReply rep; + xXF86DRIGetDeviceInfoReq *req; + + TRACE("GetDeviceInfo..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDeviceInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDeviceInfo; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + + *hFrameBuffer = rep.hFrameBufferLow; +#ifdef LONG64 + if (sizeof(drm_handle_t) == 8) { + *hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32; + } +#endif + + *fbOrigin = rep.framebufferOrigin; + *fbSize = rep.framebufferSize; + *fbStride = rep.framebufferStride; + *devPrivateSize = rep.devPrivateSize; + + if (rep.length) { + if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { + _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + _XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize); + } else { + *pDevPrivate = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return True"); + return True; +} diff --git a/tests/ttmtest/src/xf86dri.h b/tests/ttmtest/src/xf86dri.h new file mode 100644 index 0000000..8fb7896 --- /dev/null +++ b/tests/ttmtest/src/xf86dri.h @@ -0,0 +1,116 @@ +/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/** + * \file xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin + * \author Jens Owen + * \author Rickard E. (Rik) Faith + */ + +#ifndef _XF86DRI_H_ +#define _XF86DRI_H_ + +#include +#include + +#define X_XF86DRIQueryVersion 0 +#define X_XF86DRIQueryDirectRenderingCapable 1 +#define X_XF86DRIOpenConnection 2 +#define X_XF86DRICloseConnection 3 +#define X_XF86DRIGetClientDriverName 4 +#define X_XF86DRICreateContext 5 +#define X_XF86DRIDestroyContext 6 +#define X_XF86DRICreateDrawable 7 +#define X_XF86DRIDestroyDrawable 8 +#define X_XF86DRIGetDrawableInfo 9 +#define X_XF86DRIGetDeviceInfo 10 +#define X_XF86DRIAuthConnection 11 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ + +#define XF86DRINumberEvents 0 + +#define XF86DRIClientNotLocal 0 +#define XF86DRIOperationNotSupported 1 +#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) + +#ifndef _XF86DRI_SERVER_ + +_XFUNCPROTOBEGIN + Bool uniDRIQueryExtension(Display * dpy, int *event_base, + int *error_base); + +Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion, + int *patchVersion); + +Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen, + Bool * isCapable); + +Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA, + char **busIDString); + +Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic); + +Bool uniDRICloseConnection(Display * dpy, int screen); + +Bool uniDRIGetClientDriverName(Display * dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName); + +Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual, + XID * ptr_to_returned_context_id, drm_context_t * hHWContext); + +Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID, + XID * ptr_to_returned_context_id, drm_context_t * hHWContext); + +extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id); + +extern Bool uniDRICreateDrawable(Display * dpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable); + +extern Bool uniDRIDestroyDrawable(Display * dpy, int screen, + Drawable drawable); + +Bool uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t ** pBackClipRects); + +Bool uniDRIGetDeviceInfo(Display * dpy, int screen, + drm_handle_t * hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate); + +_XFUNCPROTOEND +#endif /* _XF86DRI_SERVER_ */ +#endif /* _XF86DRI_H_ */ diff --git a/tests/ttmtest/src/xf86dristr.h b/tests/ttmtest/src/xf86dristr.h new file mode 100644 index 0000000..2730d1a --- /dev/null +++ b/tests/ttmtest/src/xf86dristr.h @@ -0,0 +1,390 @@ +/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.10 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Fiath + * + */ + +#ifndef _XF86DRISTR_H_ +#define _XF86DRISTR_H_ + +#include "xf86dri.h" + +#define XF86DRINAME "XFree86-DRI" + +/* The DRI version number. This was originally set to be the same as the + * XFree86 version number. However, this version is really independent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define XF86DRI_MAJOR_VERSION 4 +#define XF86DRI_MINOR_VERSION 1 +#define XF86DRI_PATCH_VERSION 0 + +typedef struct _XF86DRIQueryVersion +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIQueryVersion */ + CARD16 length B16; +} xXF86DRIQueryVersionReq; + +#define sz_xXF86DRIQueryVersionReq 4 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DRI protocol */ + CARD16 minorVersion B16; /* minor version of DRI protocol */ + CARD32 patchVersion B32; /* patch version of DRI protocol */ + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIQueryVersionReply; + +#define sz_xXF86DRIQueryVersionReply 32 + +typedef struct _XF86DRIQueryDirectRenderingCapable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIQueryDirectRenderingCapableReq; + +#define sz_xXF86DRIQueryDirectRenderingCapableReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL isCapable; + BOOL pad2; + BOOL pad3; + BOOL pad4; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; + CARD32 pad9 B32; +} xXF86DRIQueryDirectRenderingCapableReply; + +#define sz_xXF86DRIQueryDirectRenderingCapableReply 32 + +typedef struct _XF86DRIOpenConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIOpenConnectionReq; + +#define sz_xXF86DRIOpenConnectionReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hSAREALow B32; + CARD32 hSAREAHigh B32; + CARD32 busIdStringLength B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xXF86DRIOpenConnectionReply; + +#define sz_xXF86DRIOpenConnectionReply 32 + +typedef struct _XF86DRIAuthConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; + CARD32 magic B32; +} xXF86DRIAuthConnectionReq; + +#define sz_xXF86DRIAuthConnectionReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIAuthConnectionReply; + +#define zx_xXF86DRIAuthConnectionReply 32 + +typedef struct _XF86DRICloseConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRICloseConnectionReq; + +#define sz_xXF86DRICloseConnectionReq 8 + +typedef struct _XF86DRIGetClientDriverName +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetClientDriverName */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetClientDriverNameReq; + +#define sz_xXF86DRIGetClientDriverNameReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ddxDriverMajorVersion B32; + CARD32 ddxDriverMinorVersion B32; + CARD32 ddxDriverPatchVersion B32; + CARD32 clientDriverNameLength B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIGetClientDriverNameReply; + +#define sz_xXF86DRIGetClientDriverNameReply 32 + +typedef struct _XF86DRICreateContext +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 visual B32; + CARD32 context B32; +} xXF86DRICreateContextReq; + +#define sz_xXF86DRICreateContextReq 16 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWContext B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateContextReply; + +#define sz_xXF86DRICreateContextReply 32 + +typedef struct _XF86DRIDestroyContext +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 context B32; +} xXF86DRIDestroyContextReq; + +#define sz_xXF86DRIDestroyContextReq 12 + +typedef struct _XF86DRICreateDrawable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICreateDrawableReq; + +#define sz_xXF86DRICreateDrawableReq 12 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWDrawable B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateDrawableReply; + +#define sz_xXF86DRICreateDrawableReply 32 + +typedef struct _XF86DRIDestroyDrawable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIDestroyDrawableReq; + +#define sz_xXF86DRIDestroyDrawableReq 12 + +typedef struct _XF86DRIGetDrawableInfo +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDrawableInfo */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIGetDrawableInfoReq; + +#define sz_xXF86DRIGetDrawableInfoReq 12 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 drawableTableIndex B32; + CARD32 drawableTableStamp B32; + INT16 drawableX B16; + INT16 drawableY B16; + INT16 drawableWidth B16; + INT16 drawableHeight B16; + CARD32 numClipRects B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; +} xXF86DRIGetDrawableInfoReply; + +#define sz_xXF86DRIGetDrawableInfoReply 36 + +typedef struct _XF86DRIGetDeviceInfo +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDeviceInfo */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetDeviceInfoReq; + +#define sz_xXF86DRIGetDeviceInfoReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hFrameBufferLow B32; + CARD32 hFrameBufferHigh B32; + CARD32 framebufferOrigin B32; + CARD32 framebufferSize B32; + CARD32 framebufferStride B32; + CARD32 devPrivateSize B32; +} xXF86DRIGetDeviceInfoReply; + +#define sz_xXF86DRIGetDeviceInfoReply 32 + +typedef struct _XF86DRIOpenFullScreen +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIOpenFullScreenReq; + +#define sz_xXF86DRIOpenFullScreenReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isFullScreen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIOpenFullScreenReply; + +#define sz_xXF86DRIOpenFullScreenReply 32 + +typedef struct _XF86DRICloseFullScreen +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICloseFullScreenReq; + +#define sz_xXF86DRICloseFullScreenReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xXF86DRICloseFullScreenReply; + +#define sz_xXF86DRICloseFullScreenReply 32 + +#endif /* _XF86DRISTR_H_ */ diff --git a/tests/util/Android.mk b/tests/util/Android.mk new file mode 100644 index 0000000..12eccb4 --- /dev/null +++ b/tests/util/Android.mk @@ -0,0 +1,38 @@ +# +# Copyright © 2015 NVIDIA Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_util + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(UTIL_FILES) + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LIBDRM_TOP)/tests + +include $(LIBDRM_COMMON_MK) +include $(BUILD_STATIC_LIBRARY) diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 48708d2..1c2b519 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -33,7 +33,7 @@ #include #include #include -#ifdef HAVE_SYS_SELECT_H +#if HAVE_SYS_SELECT_H #include #endif diff --git a/xf86atomic.h b/xf86atomic.h index 2d733bd..efa47a7 100644 --- a/xf86atomic.h +++ b/xf86atomic.h @@ -54,6 +54,7 @@ typedef struct { #endif #if HAVE_LIB_ATOMIC_OPS +#define AO_REQUIRE_CAS #include #define HAS_ATOMIC_OPS 1 diff --git a/xf86drm.c b/xf86drm.c index b7d5865..d240f95 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -2964,10 +2964,10 @@ sysfs_uevent_get(const char *path, const char *fmt, ...) /* Little white lie to avoid major rework of the existing code */ #define DRM_BUS_VIRTIO 0x10 -static int drmParseSubsystemType(int maj, int min) -{ #ifdef __linux__ - char path[PATH_MAX + 1]; +static int get_subsystem_type(const char *device_path) +{ + char path[PATH_MAX + 1] = ""; char link[PATH_MAX + 1] = ""; char *name; struct { @@ -2982,8 +2982,8 @@ static int drmParseSubsystemType(int maj, int min) { "/virtio", DRM_BUS_VIRTIO }, }; - snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/subsystem", - maj, min); + strncpy(path, device_path, PATH_MAX); + strncat(path, "/subsystem", PATH_MAX); if (readlink(path, link, PATH_MAX) < 0) return -errno; @@ -2998,6 +2998,27 @@ static int drmParseSubsystemType(int maj, int min) } return -EINVAL; +} +#endif + +static int drmParseSubsystemType(int maj, int min) +{ +#ifdef __linux__ + char path[PATH_MAX + 1] = ""; + char real_path[PATH_MAX + 1] = ""; + int subsystem_type; + + snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); + if (!realpath(path, real_path)) + return -errno; + snprintf(path, sizeof(path), "%s", real_path); + + subsystem_type = get_subsystem_type(path); + if (subsystem_type == DRM_BUS_VIRTIO) { + strncat(path, "/..", PATH_MAX); + subsystem_type = get_subsystem_type(path); + } + return subsystem_type; #elif defined(__OpenBSD__) || defined(__DragonFly__) return DRM_BUS_PCI; #else @@ -3699,7 +3720,6 @@ process_device(drmDevicePtr *device, const char *d_name, switch (subsystem_type) { case DRM_BUS_PCI: - case DRM_BUS_VIRTIO: return drmProcessPciDevice(device, node, node_type, maj, min, fetch_deviceinfo, flags); case DRM_BUS_USB: @@ -4252,6 +4272,21 @@ drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points, return 0; } +drm_public int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points, + uint32_t handle_count, uint32_t flags) +{ + struct drm_syncobj_timeline_array args; + + memclear(args); + args.handles = (uintptr_t)handles; + args.points = (uintptr_t)points; + args.count_handles = handle_count; + args.flags = flags; + + return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args); +} + + drm_public int drmSyncobjTransfer(int fd, uint32_t dst_handle, uint64_t dst_point, uint32_t src_handle, uint64_t src_point, diff --git a/xf86drm.h b/xf86drm.h index 3f52cd8..7b85079 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -481,6 +481,29 @@ do { register unsigned int __old __asm("o0"); \ : "cr0", "memory"); \ } while (0) +# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ + || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) \ + || defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7EM__) + /* excluding ARMv4/ARMv5 and lower (lacking ldrex/strex support) */ + #undef DRM_DEV_MODE + #define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) + + #define DRM_CAS(lock,old,new,__ret) \ + do { \ + __asm__ __volatile__ ( \ + "1: ldrex %0, [%1]\n" \ + " teq %0, %2\n" \ + " ite eq\n" \ + " strexeq %0, %3, [%1]\n" \ + " movne %0, #1\n" \ + : "=&r" (__ret) \ + : "r" (lock), "r" (old), "r" (new) \ + : "cc","memory"); \ + } while (0) + #endif /* architecture */ #endif /* __GNUC__ >= 2 */ @@ -896,6 +919,8 @@ extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points, uint32_t *first_signaled); extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points, uint32_t handle_count); +extern int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points, + uint32_t handle_count, uint32_t flags); extern int drmSyncobjTransfer(int fd, uint32_t dst_handle, uint64_t dst_point, uint32_t src_handle, uint64_t src_point, diff --git a/xf86drmMode.c b/xf86drmMode.c index 207d7be..2399e8e 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -42,7 +42,7 @@ #include #include #include -#ifdef HAVE_SYS_SYSCTL_H +#if HAVE_SYS_SYSCTL_H #include #endif #include @@ -1594,3 +1594,38 @@ drmModeRevokeLease(int fd, uint32_t lessee_id) return 0; return -errno; } + +drm_public drmModeFB2Ptr +drmModeGetFB2(int fd, uint32_t fb_id) +{ + struct drm_mode_fb_cmd2 get = { + .fb_id = fb_id, + }; + drmModeFB2Ptr ret; + int err; + + err = DRM_IOCTL(fd, DRM_IOCTL_MODE_GETFB2, &get); + if (err != 0) + return NULL; + + ret = drmMalloc(sizeof(drmModeFB2)); + if (!ret) + return NULL; + + ret->fb_id = fb_id; + ret->width = get.width; + ret->height = get.height; + ret->pixel_format = get.pixel_format; + ret->flags = get.flags; + ret->modifier = get.modifier[0]; + memcpy(ret->handles, get.handles, sizeof(uint32_t) * 4); + memcpy(ret->pitches, get.pitches, sizeof(uint32_t) * 4); + memcpy(ret->offsets, get.offsets, sizeof(uint32_t) * 4); + + return ret; +} + +drm_public void drmModeFreeFB2(drmModeFB2Ptr ptr) +{ + drmFree(ptr); +} diff --git a/xf86drmMode.h b/xf86drmMode.h index a32902f..5449320 100644 --- a/xf86drmMode.h +++ b/xf86drmMode.h @@ -41,6 +41,8 @@ extern "C" { #endif #include +#include +#include /* * This is the interface for modesetting for drm. @@ -160,6 +162,7 @@ extern "C" { #define DRM_MODE_CONNECTOR_VIRTUAL 15 #define DRM_MODE_CONNECTOR_DSI 16 #define DRM_MODE_CONNECTOR_DPI 17 +#define DRM_MODE_CONNECTOR_WRITEBACK 18 #define DRM_MODE_PROP_PENDING (1<<0) #define DRM_MODE_PROP_RANGE (1<<1) @@ -223,6 +226,19 @@ typedef struct _drmModeFB { uint32_t handle; } drmModeFB, *drmModeFBPtr; +typedef struct _drmModeFB2 { + uint32_t fb_id; + uint32_t width, height; + uint32_t pixel_format; /* fourcc code from drm_fourcc.h */ + uint64_t modifier; /* applies to all buffers */ + uint32_t flags; + + /* per-plane GEM handle; may be duplicate entries for multiple planes */ + uint32_t handles[4]; + uint32_t pitches[4]; /* bytes */ + uint32_t offsets[4]; /* bytes */ +} drmModeFB2, *drmModeFB2Ptr; + typedef struct drm_clip_rect drmModeClip, *drmModeClipPtr; typedef struct _drmModePropertyBlob { @@ -341,6 +357,7 @@ typedef struct _drmModePlaneRes { extern void drmModeFreeModeInfo( drmModeModeInfoPtr ptr ); extern void drmModeFreeResources( drmModeResPtr ptr ); extern void drmModeFreeFB( drmModeFBPtr ptr ); +extern void drmModeFreeFB2( drmModeFB2Ptr ptr ); extern void drmModeFreeCrtc( drmModeCrtcPtr ptr ); extern void drmModeFreeConnector( drmModeConnectorPtr ptr ); extern void drmModeFreeEncoder( drmModeEncoderPtr ptr ); @@ -360,6 +377,7 @@ extern drmModeResPtr drmModeGetResources(int fd); * Retrieve information about framebuffer bufferId */ extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId); +extern drmModeFB2Ptr drmModeGetFB2(int fd, uint32_t bufferId); /** * Creates a new framebuffer with an buffer object as its scanout buffer.