v3d/simulator: add support for AMD cards

Dumb buffers do not work with AMD gpus. So use AMD ioctl to create
proper buffers.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16187>
This commit is contained in:
Juan A. Suarez Romero 2022-04-27 11:32:00 +02:00 committed by Marge Bot
parent 9c3144d2ef
commit 031bcf686b
2 changed files with 53 additions and 11 deletions

View File

@ -60,6 +60,7 @@
#include "util/u_math.h"
#include <xf86drm.h>
#include "drm-uapi/amdgpu_drm.h"
#include "drm-uapi/i915_drm.h"
#include "drm-uapi/v3d_drm.h"
@ -96,6 +97,12 @@ static struct v3d_simulator_state {
.mutex = _MTX_INITIALIZER_NP,
};
enum gem_type {
GEM_I915,
GEM_AMDGPU,
GEM_DUMB
};
/** Per-GEM-fd state for the simulator. */
struct v3d_simulator_file {
int fd;
@ -111,8 +118,8 @@ struct v3d_simulator_file {
struct mem_block *gmp;
void *gmp_vaddr;
/** Actual GEM fd is i915, so we should use their create ioctl. */
bool is_i915;
/** For specific gpus, use their create ioctl. Otherwise use dumb bo. */
enum gem_type gem_type;
};
/** Wrapper for drm_v3d_bo tracking the simulator-specific state. */
@ -241,7 +248,9 @@ v3d_create_simulator_bo_for_gem(int fd, int handle, unsigned size)
* one.
*/
int ret;
if (file->is_i915) {
switch (file->gem_type) {
case GEM_I915:
{
struct drm_i915_gem_mmap_gtt map = {
.handle = handle,
};
@ -252,14 +261,26 @@ v3d_create_simulator_bo_for_gem(int fd, int handle, unsigned size)
*/
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &map);
sim_bo->mmap_offset = map.offset;
} else {
break;
}
case GEM_AMDGPU:
{
union drm_amdgpu_gem_mmap map = { 0 };
map.in.handle = handle;
ret = drmIoctl(fd, DRM_IOCTL_AMDGPU_GEM_MMAP, &map);
sim_bo->mmap_offset = map.out.addr_ptr;
break;
}
default:
{
struct drm_mode_map_dumb map = {
.handle = handle,
};
ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
sim_bo->mmap_offset = map.offset;
}
}
if (ret) {
fprintf(stderr, "Failed to get MMAP offset: %d\n", ret);
abort();
@ -519,14 +540,30 @@ v3d_simulator_create_bo_ioctl(int fd, struct drm_v3d_create_bo *args)
* native ioctl in case we're on a render node.
*/
int ret;
if (file->is_i915) {
switch (file->gem_type) {
case GEM_I915:
{
struct drm_i915_gem_create create = {
.size = args->size,
};
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
args->handle = create.handle;
} else {
break;
}
case GEM_AMDGPU:
{
union drm_amdgpu_gem_create create = { 0 };
create.in.bo_size = args->size;
ret = drmIoctl(fd, DRM_IOCTL_AMDGPU_GEM_CREATE, &create);
args->handle = create.out.handle;
break;
}
default:
{
struct drm_mode_create_dumb create = {
.width = 128,
.bpp = 8,
@ -538,7 +575,7 @@ v3d_simulator_create_bo_ioctl(int fd, struct drm_v3d_create_bo *args)
args->handle = create.handle;
}
}
if (ret == 0) {
struct v3d_simulator_bo *sim_bo =
v3d_create_simulator_bo_for_gem(fd, args->handle,
@ -847,7 +884,11 @@ v3d_simulator_init(int fd)
drmVersionPtr version = drmGetVersion(fd);
if (version && strncmp(version->name, "i915", version->name_len) == 0)
sim_file->is_i915 = true;
sim_file->gem_type = GEM_I915;
else if (version && strncmp(version->name, "amdgpu", version->name_len) == 0)
sim_file->gem_type = GEM_AMDGPU;
else
sim_file->gem_type = GEM_DUMB;
drmFreeVersion(version);
sim_file->bo_map =

View File

@ -933,11 +933,12 @@ enumerate_devices(struct v3dv_instance *instance)
#endif
for (unsigned i = 0; i < (unsigned)max_devices; i++) {
#if using_v3d_simulator
/* In the simulator, we look for an Intel render node */
/* In the simulator, we look for an Intel/AMD render node */
const int required_nodes = (1 << DRM_NODE_RENDER) | (1 << DRM_NODE_PRIMARY);
if ((devices[i]->available_nodes & required_nodes) == required_nodes &&
devices[i]->bustype == DRM_BUS_PCI &&
devices[i]->deviceinfo.pci->vendor_id == 0x8086) {
(devices[i]->deviceinfo.pci->vendor_id == 0x8086 ||
devices[i]->deviceinfo.pci->vendor_id == 0x1002)) {
result = physical_device_init(&instance->physicalDevice, instance,
devices[i], NULL);
if (result != VK_ERROR_INCOMPATIBLE_DRIVER)