diff --git a/src/amd/drm-shim/README.md b/src/amd/drm-shim/README.md new file mode 100644 index 00000000000..9a41849b9ed --- /dev/null +++ b/src/amd/drm-shim/README.md @@ -0,0 +1,10 @@ +### radeon_noop backend + +This implements the minimum of the radeon kernel driver in order to make shader-db work. +The submit ioctl is stubbed out to not execute anything. + +Export `MESA_LOADER_DRIVER_OVERRIDE=r300 +LD_PRELOAD=$prefix/lib/libradeon_noop_drm_shim.so`. (or r600 for r600-class HW) + +By default, rv515 is exposed. The chip can be selected an enviornment +variable like `RADEON_GPU_ID=CAYMAN` or `RADEON_GPU_ID=0x6740`. diff --git a/src/amd/drm-shim/meson.build b/src/amd/drm-shim/meson.build new file mode 100644 index 00000000000..dd0b86d547b --- /dev/null +++ b/src/amd/drm-shim/meson.build @@ -0,0 +1,29 @@ +# Copyright © 2021 Emma Anholt +# +# 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. + +libradeon_noop_drm_shim = shared_library( + ['radeon_noop_drm_shim'], + 'radeon_noop_drm_shim.c', + include_directories: [inc_include, inc_src, inc_amd], + dependencies: dep_drm_shim, + gnu_symbol_visibility : 'hidden', + install : true, +) diff --git a/src/amd/drm-shim/radeon_noop_drm_shim.c b/src/amd/drm-shim/radeon_noop_drm_shim.c new file mode 100644 index 00000000000..8b1a2743c80 --- /dev/null +++ b/src/amd/drm-shim/radeon_noop_drm_shim.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include "common/amd_family.h" +#include "drm-shim/drm_shim.h" +#include "util/log.h" +#include +#include + +bool drm_shim_driver_prefers_first_render_node = true; + +static enum radeon_family radeon_family = CHIP_RV515; +static uint16_t device_id = 0x7140; + +static int +radeon_ioctl_noop(int fd, unsigned long request, void *arg) +{ + return 0; +} + +static int +radeon_ioctl_info(int fd, unsigned long request, void *arg) +{ + struct drm_radeon_info *info = arg; + uint32_t *value = (uint32_t *)(intptr_t)info->value; + + switch (info->request) { + case RADEON_INFO_DEVICE_ID: + *value = device_id; + return 0; + + case RADEON_INFO_RING_WORKING: + case RADEON_INFO_ACCEL_WORKING2: + case RADEON_INFO_VA_UNMAP_WORKING: + *value = true; + return 0; + + case RADEON_INFO_GPU_RESET_COUNTER: + *value = 0; + return 0; + + case RADEON_INFO_IB_VM_MAX_SIZE: + if (radeon_family < CHIP_CAYMAN) + return -EINVAL; + *value = 64 << 10; + return 0; + + case RADEON_INFO_VCE_FW_VERSION: + case RADEON_INFO_TILING_CONFIG: + case RADEON_INFO_BACKEND_MAP: + *value = 0; /* dummy */ + return 0; + + case RADEON_INFO_VA_START: + return 4096; + + case RADEON_INFO_MAX_SCLK: + case RADEON_INFO_CLOCK_CRYSTAL_FREQ: + case RADEON_INFO_NUM_GB_PIPES: + case RADEON_INFO_NUM_Z_PIPES: + case RADEON_INFO_MAX_PIPES: + case RADEON_INFO_MAX_SE: + case RADEON_INFO_MAX_SH_PER_SE: + case RADEON_INFO_ACTIVE_CU_COUNT: + case RADEON_INFO_NUM_BACKENDS: + case RADEON_INFO_NUM_TILE_PIPES: + *value = 1; /* dummy */ + return 0; + + default: + fprintf(stderr, "Unknown DRM_IOCTL_RADEON_INFO request 0x%02X\n", info->request); + return -1; + } +} + +static int +radeon_ioctl_gem_info(int fd, unsigned long request, void *arg) +{ + struct drm_radeon_gem_info *info = arg; + + /* Dummy values. */ + info->vram_size = 256 * 1024 * 1024; + info->vram_visible = info->vram_size; + info->gart_size = 512 * 1024 * 1024; + + return 0; +} + +static int +radeon_ioctl_gem_create(int fd, unsigned long request, void *arg) +{ + struct drm_radeon_gem_create *create = arg; + + struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); + struct shim_bo *bo = calloc(1, sizeof(*bo)); + size_t size = ALIGN(create->size, 4096); + + drm_shim_bo_init(bo, size); + + create->handle = drm_shim_bo_get_handle(shim_fd, bo); + + drm_shim_bo_put(bo); + + return 0; +} + +static int +radeon_ioctl_gem_mmap(int fd, unsigned long request, void *arg) +{ + struct drm_radeon_gem_mmap *mmap_bo = arg; + + struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); + struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, mmap_bo->handle); + + mmap_bo->addr_ptr = drm_shim_bo_get_mmap_offset(shim_fd, bo); + + return 0; +} + +static int +radeon_ioctl_gem_userptr(int fd, unsigned long request, void *arg) +{ + /* probed at winsys init, just return no support. */ + return -EINVAL; +} + +static ioctl_fn_t driver_ioctls[] = { + [DRM_RADEON_CS] = radeon_ioctl_noop, + [DRM_RADEON_INFO] = radeon_ioctl_info, + [DRM_RADEON_GEM_SET_DOMAIN] = radeon_ioctl_noop, + [DRM_RADEON_GEM_SET_TILING] = radeon_ioctl_noop, + [DRM_RADEON_GEM_WAIT_IDLE] = radeon_ioctl_noop, + [DRM_RADEON_GEM_INFO] = radeon_ioctl_gem_info, + [DRM_RADEON_GEM_CREATE] = radeon_ioctl_gem_create, + [DRM_RADEON_GEM_MMAP] = radeon_ioctl_gem_mmap, + [DRM_RADEON_GEM_USERPTR] = radeon_ioctl_gem_userptr, +}; + +struct radeon_pci_id { + uint16_t device_id; + const char *name; + enum radeon_family family; + const char *family_name; +}; + +#define CHIPSET(d, n, f) {.device_id = (d), .name = #n, .family = CHIP_##f, .family_name = #f}, +static const struct radeon_pci_id radeon_pci_ids[] = { +#include "pci_ids/r300_pci_ids.h" +#include "pci_ids/r600_pci_ids.h" +}; +#undef CHIPSET + +static void +radeon_get_device_id() +{ + const char *gpu_id = getenv("RADEON_GPU_ID"); + if (!gpu_id) + return; + + if (strncmp(gpu_id, "0x", 2) == 0) { + device_id = strtoll(gpu_id + 2, NULL, 16); + return; + } + + for (int i = 0; i < ARRAY_SIZE(radeon_pci_ids); i++) { + if (strcasecmp(gpu_id, radeon_pci_ids[i].name) == 0 || + strcasecmp(gpu_id, radeon_pci_ids[i].family_name) == 0) { + device_id = radeon_pci_ids[i].device_id; + return; + } + } + + mesa_loge("Failed to find radeon GPU named \"%s\"\n", gpu_id); + abort(); +} + +void +drm_shim_driver_init(void) +{ + radeon_get_device_id(); + + shim_device.bus_type = DRM_BUS_PCI; + shim_device.driver_name = "radeon"; + shim_device.driver_ioctls = driver_ioctls; + shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls); + + shim_device.version_major = 2; + shim_device.version_minor = 50; + shim_device.version_patchlevel = 0; +} diff --git a/src/amd/meson.build b/src/amd/meson.build index 463c78544ab..37f9b570437 100644 --- a/src/amd/meson.build +++ b/src/amd/meson.build @@ -34,3 +34,7 @@ if with_amd_vk subdir('compiler/tests') endif endif + +if with_tools.contains('drm-shim') + subdir('drm-shim') +endif