From c80e267a0a946959c8dc978413a8e8e31c497799 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 2 Nov 2018 12:03:36 -0700 Subject: [PATCH] vc4: Maintain a separate GEM mapping of BOs in the simulator. This will let us avoid looking back into the gallium driver's vc4_bo. --- src/gallium/drivers/vc4/vc4_simulator.c | 99 +++++++++++-------- .../drivers/vc4/vc4_simulator_validate.h | 1 - 2 files changed, 58 insertions(+), 42 deletions(-) diff --git a/src/gallium/drivers/vc4/vc4_simulator.c b/src/gallium/drivers/vc4/vc4_simulator.c index 53f1fc5ba7e..46fed7bcdb8 100644 --- a/src/gallium/drivers/vc4/vc4_simulator.c +++ b/src/gallium/drivers/vc4/vc4_simulator.c @@ -101,6 +101,11 @@ struct vc4_simulator_bo { struct mem_block *block; int handle; + + /* Mapping of the underlying GEM object that we copy in/out of + * simulator memory. + */ + void *gem_vaddr; }; static void * @@ -141,6 +146,7 @@ vc4_create_simulator_bo(int fd, int handle, unsigned size) sim_bo->file = file; sim_bo->handle = handle; + /* Allocate space for the buffer in simulator memory. */ mtx_lock(&sim_state.mutex); sim_bo->block = u_mmAllocMem(sim_state.heap, size + 4, PAGE_ALIGN2, 0); mtx_unlock(&sim_state.mutex); @@ -160,6 +166,25 @@ vc4_create_simulator_bo(int fd, int handle, unsigned size) mtx_lock(&sim_state.mutex); _mesa_hash_table_insert(file->bo_map, int_to_key(handle), bo); mtx_unlock(&sim_state.mutex); + + /* Map the GEM buffer for copy in/out to the simulator. */ + struct drm_mode_map_dumb map = { + .handle = handle, + }; + int ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map); + if (ret) { + fprintf(stderr, "Failed to get MMAP offset: %d\n", + errno); + abort(); + } + sim_bo->gem_vaddr = mmap(NULL, obj->base.size, + PROT_READ | PROT_WRITE, MAP_SHARED, + fd, map.offset); + if (sim_bo->gem_vaddr == MAP_FAILED) { + fprintf(stderr, "mmap of bo %d (offset 0x%016llx, size %d) failed\n", + handle, (long long)map.offset, (int)obj->base.size); + abort(); + } } return sim_bo; @@ -169,6 +194,16 @@ static void vc4_free_simulator_bo(struct vc4_simulator_bo *sim_bo) { struct vc4_simulator_file *sim_file = sim_bo->file; + struct drm_vc4_bo *bo = &sim_bo->base; + struct drm_gem_cma_object *obj = &bo->base; + + if (bo->validated_shader) { + free(bo->validated_shader->texture_samples); + free(bo->validated_shader); + } + + if (sim_bo->gem_vaddr) + munmap(sim_bo->gem_vaddr, obj->base.size); mtx_lock(&sim_state.mutex); u_mmFreeMem(sim_bo->block); @@ -201,41 +236,23 @@ drm_gem_cma_create(struct drm_device *dev, size_t size) } static int -vc4_simulator_pin_bos(struct drm_device *dev, struct vc4_job *job, +vc4_simulator_pin_bos(struct vc4_simulator_file *file, struct vc4_exec_info *exec) { - int fd = dev->screen->fd; - struct vc4_simulator_file *file = vc4_get_simulator_file_for_fd(fd); struct drm_vc4_submit_cl *args = exec->args; - struct vc4_bo **bos = job->bo_pointers.base; + uint32_t *bo_handles = (uint32_t *)(uintptr_t)args->bo_handles; exec->bo_count = args->bo_handle_count; exec->bo = calloc(exec->bo_count, sizeof(void *)); for (int i = 0; i < exec->bo_count; i++) { - struct vc4_bo *bo = bos[i]; struct vc4_simulator_bo *sim_bo = - vc4_get_simulator_bo(file, bo->handle); + vc4_get_simulator_bo(file, bo_handles[i]); struct drm_vc4_bo *drm_bo = &sim_bo->base; struct drm_gem_cma_object *obj = &drm_bo->base; - drm_bo->bo = bo; -#if 0 - fprintf(stderr, "bo hindex %d: %s\n", i, bo->name); -#endif - - vc4_bo_map(bo); - memcpy(obj->vaddr, bo->map, bo->size); + memcpy(obj->vaddr, sim_bo->gem_vaddr, obj->base.size); exec->bo[i] = obj; - - /* The kernel does this validation at shader create ioctl - * time. - */ - if (strcmp(bo->name, "code") == 0) { - drm_bo->validated_shader = vc4_validate_shader(obj); - if (!drm_bo->validated_shader) - abort(); - } } return 0; } @@ -246,16 +263,13 @@ vc4_simulator_unpin_bos(struct vc4_exec_info *exec) for (int i = 0; i < exec->bo_count; i++) { struct drm_gem_cma_object *obj = exec->bo[i]; struct drm_vc4_bo *drm_bo = to_vc4_bo(&obj->base); - struct vc4_bo *bo = drm_bo->bo; + struct vc4_simulator_bo *sim_bo = + (struct vc4_simulator_bo *)drm_bo; assert(*(uint32_t *)(obj->vaddr + obj->base.size) == BO_SENTINEL); - memcpy(bo->map, obj->vaddr, bo->size); - - if (drm_bo->validated_shader) { - free(drm_bo->validated_shader->texture_samples); - free(drm_bo->validated_shader); - } + if (sim_bo->gem_vaddr) + memcpy(sim_bo->gem_vaddr, obj->vaddr, obj->base.size); } free(exec->bo); @@ -366,7 +380,7 @@ vc4_simulator_flush(struct vc4_context *vc4, exec.args = args; - ret = vc4_simulator_pin_bos(dev, job, &exec); + ret = vc4_simulator_pin_bos(file, &exec); if (ret) return ret; @@ -481,19 +495,22 @@ vc4_simulator_create_shader_bo_ioctl(int fd, args->handle = create.handle; - vc4_create_simulator_bo(fd, create.handle, args->size); + struct vc4_simulator_bo *sim_bo = + vc4_create_simulator_bo(fd, create.handle, args->size); + struct drm_vc4_bo *drm_bo = &sim_bo->base; + struct drm_gem_cma_object *obj = &drm_bo->base; - struct drm_mode_map_dumb map = { - .handle = create.handle - }; - ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map); - if (ret) - return ret; + /* Copy into the simulator's BO for validation. */ + memcpy(obj->vaddr, (void *)(uintptr_t)args->data, args->size); + + /* Copy into the GEM BO to prevent the simulator_pin_bos() from + * smashing it. + */ + memcpy(sim_bo->gem_vaddr, (void *)(uintptr_t)args->data, args->size); - 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); + drm_bo->validated_shader = vc4_validate_shader(obj); + if (!drm_bo->validated_shader) + return -EINVAL; return 0; } diff --git a/src/gallium/drivers/vc4/vc4_simulator_validate.h b/src/gallium/drivers/vc4/vc4_simulator_validate.h index d507b5fb632..e2777cd5432 100644 --- a/src/gallium/drivers/vc4/vc4_simulator_validate.h +++ b/src/gallium/drivers/vc4/vc4_simulator_validate.h @@ -94,7 +94,6 @@ struct drm_gem_cma_object { struct drm_vc4_bo { struct drm_gem_cma_object base; - struct vc4_bo *bo; struct vc4_validated_shader_info *validated_shader; struct list_head unref_head; }; -- 2.30.2