diff options
-rw-r--r-- | src/gallium/drivers/vc4/vc4_bufmgr.c | 98 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_context.h | 11 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_screen.c | 15 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_simulator.c | 139 |
5 files changed, 182 insertions, 84 deletions
diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.c b/src/gallium/drivers/vc4/vc4_bufmgr.c index cf6a5114b87..350761ee86c 100644 --- a/src/gallium/drivers/vc4/vc4_bufmgr.c +++ b/src/gallium/drivers/vc4/vc4_bufmgr.c @@ -148,28 +148,17 @@ vc4_bo_alloc(struct vc4_screen *screen, uint32_t size, const char *name) bo->name = name; bo->private = true; + retry: + ; + bool cleared_and_retried = false; -retry: - if (!using_vc4_simulator) { - struct drm_vc4_create_bo create; - memset(&create, 0, sizeof(create)); - - create.size = size; - - ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_CREATE_BO, &create); - bo->handle = create.handle; - } else { - struct drm_mode_create_dumb create; - memset(&create, 0, sizeof(create)); - - create.width = 128; - create.bpp = 8; - create.height = (size + 127) / 128; - - ret = drmIoctl(screen->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create); - bo->handle = create.handle; - assert(create.size >= size); - } + struct drm_vc4_create_bo create = { + .size = size + }; + + ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_CREATE_BO, &create); + bo->handle = create.handle; + if (ret != 0) { if (!list_empty(&screen->bo_cache.time_list) && !cleared_and_retried) { @@ -223,7 +212,7 @@ vc4_bo_free(struct vc4_bo *bo) struct drm_gem_close c; memset(&c, 0, sizeof(c)); c.handle = bo->handle; - int ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_CLOSE, &c); + int ret = vc4_ioctl(screen->fd, DRM_IOCTL_GEM_CLOSE, &c); if (ret != 0) fprintf(stderr, "close object %d: %s\n", bo->handle, strerror(errno)); @@ -380,7 +369,7 @@ vc4_bo_open_name(struct vc4_screen *screen, uint32_t name, struct drm_gem_open o = { .name = name }; - int ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o); + int ret = vc4_ioctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o); if (ret) { fprintf(stderr, "Failed to open bo %d: %s\n", name, strerror(errno)); @@ -447,30 +436,15 @@ vc4_bo_alloc_shader(struct vc4_screen *screen, const void *data, uint32_t size) bo->name = "code"; bo->private = false; /* Make sure it doesn't go back to the cache. */ - if (!using_vc4_simulator) { - struct drm_vc4_create_shader_bo create = { - .size = size, - .data = (uintptr_t)data, - }; - - ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_CREATE_SHADER_BO, - &create); - bo->handle = create.handle; - } else { - struct drm_mode_create_dumb create; - memset(&create, 0, sizeof(create)); - - create.width = 128; - create.bpp = 8; - create.height = (size + 127) / 128; - - ret = drmIoctl(screen->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create); - bo->handle = create.handle; - assert(create.size >= size); - - vc4_bo_map(bo); - memcpy(bo->map, data, size); - } + struct drm_vc4_create_shader_bo create = { + .size = size, + .data = (uintptr_t)data, + }; + + ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_CREATE_SHADER_BO, + &create); + bo->handle = create.handle; + if (ret != 0) { fprintf(stderr, "create shader ioctl failure\n"); abort(); @@ -492,7 +466,7 @@ vc4_bo_flink(struct vc4_bo *bo, uint32_t *name) struct drm_gem_flink flink = { .handle = bo->handle, }; - int ret = drmIoctl(bo->screen->fd, DRM_IOCTL_GEM_FLINK, &flink); + int ret = vc4_ioctl(bo->screen->fd, DRM_IOCTL_GEM_FLINK, &flink); if (ret) { fprintf(stderr, "Failed to flink bo %d: %s\n", bo->handle, strerror(errno)); @@ -508,14 +482,11 @@ vc4_bo_flink(struct vc4_bo *bo, uint32_t *name) static int vc4_wait_seqno_ioctl(int fd, uint64_t seqno, uint64_t timeout_ns) { - if (using_vc4_simulator) - return 0; - struct drm_vc4_wait_seqno wait = { .seqno = seqno, .timeout_ns = timeout_ns, }; - int ret = drmIoctl(fd, DRM_IOCTL_VC4_WAIT_SEQNO, &wait); + int ret = vc4_ioctl(fd, DRM_IOCTL_VC4_WAIT_SEQNO, &wait); if (ret == -1) return -errno; else @@ -553,14 +524,11 @@ vc4_wait_seqno(struct vc4_screen *screen, uint64_t seqno, uint64_t timeout_ns, static int vc4_wait_bo_ioctl(int fd, uint32_t handle, uint64_t timeout_ns) { - if (using_vc4_simulator) - return 0; - struct drm_vc4_wait_bo wait = { .handle = handle, .timeout_ns = timeout_ns, }; - int ret = drmIoctl(fd, DRM_IOCTL_VC4_WAIT_BO, &wait); + int ret = vc4_ioctl(fd, DRM_IOCTL_VC4_WAIT_BO, &wait); if (ret == -1) return -errno; else @@ -602,19 +570,11 @@ vc4_bo_map_unsynchronized(struct vc4_bo *bo) if (bo->map) return bo->map; - if (!using_vc4_simulator) { - struct drm_vc4_mmap_bo map; - memset(&map, 0, sizeof(map)); - map.handle = bo->handle; - ret = drmIoctl(bo->screen->fd, DRM_IOCTL_VC4_MMAP_BO, &map); - offset = map.offset; - } else { - struct drm_mode_map_dumb map; - memset(&map, 0, sizeof(map)); - map.handle = bo->handle; - ret = drmIoctl(bo->screen->fd, DRM_IOCTL_MODE_MAP_DUMB, &map); - offset = map.offset; - } + struct drm_vc4_mmap_bo map; + memset(&map, 0, sizeof(map)); + map.handle = bo->handle; + ret = vc4_ioctl(bo->screen->fd, DRM_IOCTL_VC4_MMAP_BO, &map); + offset = map.offset; if (ret != 0) { fprintf(stderr, "map ioctl failure\n"); abort(); diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h index 313630a7e2f..249caebc1bc 100644 --- a/src/gallium/drivers/vc4/vc4_context.h +++ b/src/gallium/drivers/vc4/vc4_context.h @@ -30,6 +30,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/slab.h" +#include "xf86drm.h" #define __user #include "vc4_drm.h" @@ -427,6 +428,16 @@ void vc4_simulator_destroy(struct vc4_screen *screen); int vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args, struct vc4_job *job); +int vc4_simulator_ioctl(int fd, unsigned long request, void *arg); + +static inline int +vc4_ioctl(int fd, unsigned long request, void *arg) +{ + if (using_vc4_simulator) + return vc4_simulator_ioctl(fd, request, arg); + else + return drmIoctl(fd, request, arg); +} void vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader *shader); void vc4_write_uniforms(struct vc4_context *vc4, diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 81ac070d463..c0d956c276b 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -38,9 +38,6 @@ #include "vc4_qpu.h" #include "vc4_qir.h" #include "mesa/state_tracker/st_glsl_types.h" -#ifdef USE_VC4_SIMULATOR -#include "simpenrose/simpenrose.h" -#endif static struct qreg ntq_get_src(struct vc4_compile *c, nir_src src, int i); diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c index 72fd09aee4f..37bca30b1b9 100644 --- a/src/gallium/drivers/vc4/vc4_screen.c +++ b/src/gallium/drivers/vc4/vc4_screen.c @@ -528,14 +528,10 @@ static int handle_compare(void *key1, void *key2) static bool vc4_supports_branches(struct vc4_screen *screen) { -#if USE_VC4_SIMULATOR - return true; -#endif - struct drm_vc4_get_param p = { .param = DRM_VC4_PARAM_SUPPORTS_BRANCHES, }; - int ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p); + int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p); if (ret != 0) return false; @@ -546,11 +542,6 @@ vc4_supports_branches(struct vc4_screen *screen) static bool vc4_get_chip_info(struct vc4_screen *screen) { -#if USE_VC4_SIMULATOR - screen->v3d_ver = 21; - return true; -#endif - struct drm_vc4_get_param ident0 = { .param = DRM_VC4_PARAM_V3D_IDENT0, }; @@ -559,7 +550,7 @@ vc4_get_chip_info(struct vc4_screen *screen) }; int ret; - ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0); + ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0); if (ret != 0) { if (errno == EINVAL) { /* Backwards compatibility with 2835 kernels which @@ -573,7 +564,7 @@ vc4_get_chip_info(struct vc4_screen *screen) return false; } } - ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1); + ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1); if (ret != 0) { fprintf(stderr, "Couldn't get V3D IDENT1: %s\n", strerror(errno)); diff --git a/src/gallium/drivers/vc4/vc4_simulator.c b/src/gallium/drivers/vc4/vc4_simulator.c index 0291a4e1458..76896c06e73 100644 --- a/src/gallium/drivers/vc4/vc4_simulator.c +++ b/src/gallium/drivers/vc4/vc4_simulator.c @@ -23,6 +23,8 @@ #ifdef USE_VC4_SIMULATOR +#include <sys/mman.h> +#include "xf86drm.h" #include "util/u_memory.h" #include "util/ralloc.h" @@ -320,6 +322,143 @@ vc4_simulator_flush(struct vc4_context *vc4, return 0; } +/** + * Simulated ioctl(fd, DRM_VC4_CREATE_BO) implementation. + * + * Making a VC4 BO is just a matter of making a corresponding BO on the host. + */ +static int +vc4_simulator_create_bo_ioctl(int fd, struct drm_vc4_create_bo *args) +{ + int ret; + struct drm_mode_create_dumb create = { + .width = 128, + .bpp = 8, + .height = (args->size + 127) / 128, + }; + + ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create); + assert(create.size >= args->size); + + args->handle = create.handle; + + return ret; +} + +/** + * Simulated ioctl(fd, DRM_VC4_CREATE_SHADER_BO) implementation. + * + * In simulation we defer shader validation until exec time. Just make a host + * BO and memcpy the contents in. + */ +static int +vc4_simulator_create_shader_bo_ioctl(int fd, + struct drm_vc4_create_shader_bo *args) +{ + int ret; + struct drm_mode_create_dumb create = { + .width = 128, + .bpp = 8, + .height = (args->size + 127) / 128, + }; + + ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create); + if (ret) + return ret; + assert(create.size >= args->size); + + args->handle = create.handle; + + struct drm_mode_map_dumb map = { + .handle = create.handle + }; + ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map); + if (ret) + return ret; + + void *shader = mmap(NULL, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, map.offset); + memcpy(shader, (void *)(uintptr_t)args->data, args->size); + munmap(shader, args->size); + + return 0; +} + +/** + * Simulated ioctl(fd, DRM_VC4_MMAP_BO) implementation. + * + * We just pass this straight through to dumb mmap. + */ +static int +vc4_simulator_mmap_bo_ioctl(int fd, struct drm_vc4_mmap_bo *args) +{ + int ret; + struct drm_mode_map_dumb map = { + .handle = args->handle, + }; + + ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map); + args->offset = map.offset; + + return ret; +} + +static int +vc4_simulator_get_param_ioctl(int fd, struct drm_vc4_get_param *args) +{ + switch (args->param) { + case DRM_VC4_PARAM_SUPPORTS_BRANCHES: + args->value = true; + return 0; + + case DRM_VC4_PARAM_V3D_IDENT0: + args->value = 0x02000000; + return 0; + + case DRM_VC4_PARAM_V3D_IDENT1: + args->value = 0x00000001; + return 0; + + default: + fprintf(stderr, "Unknown DRM_IOCTL_VC4_GET_PARAM(%lld)\n", + (long long)args->value); + abort(); + }; +} + +int +vc4_simulator_ioctl(int fd, unsigned long request, void *args) +{ + switch (request) { + case DRM_IOCTL_VC4_CREATE_BO: + return vc4_simulator_create_bo_ioctl(fd, args); + case DRM_IOCTL_VC4_CREATE_SHADER_BO: + return vc4_simulator_create_shader_bo_ioctl(fd, args); + case DRM_IOCTL_VC4_MMAP_BO: + return vc4_simulator_mmap_bo_ioctl(fd, args); + + case DRM_IOCTL_VC4_WAIT_BO: + case DRM_IOCTL_VC4_WAIT_SEQNO: + /* We do all of the vc4 rendering synchronously, so we just + * return immediately on the wait ioctls. This ignores any + * native rendering to the host BO, so it does mean we race on + * front buffer rendering. + */ + return 0; + + case DRM_IOCTL_VC4_GET_PARAM: + return vc4_simulator_get_param_ioctl(fd, args); + + case DRM_IOCTL_GEM_OPEN: + case DRM_IOCTL_GEM_CLOSE: + case DRM_IOCTL_GEM_FLINK: + return drmIoctl(fd, request, args); + default: + fprintf(stderr, "Unknown ioctl 0x%08x\n", (int)request); + abort(); + } +} + static void *sim_mem_base = NULL; static int sim_mem_refcount = 0; static ssize_t sim_mem_size = 256 * 1024 * 1024; |