diff options
Diffstat (limited to 'freedreno/freedreno_pipe.c')
-rw-r--r-- | freedreno/freedreno_pipe.c | 188 |
1 files changed, 4 insertions, 184 deletions
diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c index 9f9f1c6e..805bf008 100644 --- a/freedreno/freedreno_pipe.c +++ b/freedreno/freedreno_pipe.c @@ -29,57 +29,16 @@ #include "freedreno_drmif.h" #include "freedreno_priv.h" - -static int getprop(int fd, enum kgsl_property_type type, - void *value, int sizebytes) -{ - struct kgsl_device_getproperty req = { - .type = type, - .value = value, - .sizebytes = sizebytes, - }; - return ioctl(fd, IOCTL_KGSL_DEVICE_GETPROPERTY, &req); -} - -#define GETPROP(fd, prop, x) do { \ - if (getprop((fd), KGSL_PROP_##prop, &(x), sizeof(x))) { \ - ERROR_MSG("failed to get property: " #prop); \ - goto fail; \ - } } while (0) - - struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) { - static const char *paths[] = { - [FD_PIPE_3D] = "/dev/kgsl-3d0", - [FD_PIPE_2D] = "/dev/kgsl-2d0", - }; - struct kgsl_drawctxt_create req = { - .flags = 0x2000, /* ??? */ - }; struct fd_pipe *pipe = NULL; - int ret, fd; if (id > FD_PIPE_MAX) { ERROR_MSG("invalid pipe id: %d", id); goto fail; } - fd = open(paths[id], O_RDWR); - if (fd < 0) { - ERROR_MSG("could not open %s device: %d (%s)", - paths[id], fd, strerror(errno)); - goto fail; - } - - ret = ioctl(fd, IOCTL_KGSL_DRAWCTXT_CREATE, &req); - if (ret) { - ERROR_MSG("failed to allocate context: %d (%s)", - ret, strerror(errno)); - goto fail; - } - - pipe = calloc(1, sizeof(*pipe)); + pipe = dev->funcs->pipe_new(dev, id); if (!pipe) { ERROR_MSG("allocation failed"); goto fail; @@ -87,31 +46,6 @@ struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) pipe->dev = dev; pipe->id = id; - pipe->fd = fd; - pipe->drawctxt_id = req.drawctxt_id; - - list_inithead(&pipe->submit_list); - list_inithead(&pipe->pending_list); - - GETPROP(fd, VERSION, pipe->version); - GETPROP(fd, DEVICE_INFO, pipe->devinfo); - - INFO_MSG("Pipe Info:"); - INFO_MSG(" Device: %s", paths[id]); - INFO_MSG(" Chip-id: %d.%d.%d.%d", - (pipe->devinfo.chip_id >> 24) & 0xff, - (pipe->devinfo.chip_id >> 16) & 0xff, - (pipe->devinfo.chip_id >> 8) & 0xff, - (pipe->devinfo.chip_id >> 0) & 0xff); - INFO_MSG(" Device-id: %d", pipe->devinfo.device_id); - INFO_MSG(" GPU-id: %d", pipe->devinfo.gpu_id); - INFO_MSG(" MMU enabled: %d", pipe->devinfo.mmu_enabled); - INFO_MSG(" GMEM Base addr: 0x%08x", pipe->devinfo.gmem_gpubaseaddr); - INFO_MSG(" GMEM size: 0x%08x", pipe->devinfo.gmem_sizebytes); - INFO_MSG(" Driver version: %d.%d", - pipe->version.drv_major, pipe->version.drv_minor); - INFO_MSG(" Device version: %d.%d", - pipe->version.dev_major, pipe->version.dev_minor); return pipe; fail: @@ -122,130 +56,16 @@ fail: void fd_pipe_del(struct fd_pipe *pipe) { - struct kgsl_drawctxt_destroy req = { - .drawctxt_id = pipe->drawctxt_id, - }; - - if (pipe->drawctxt_id) - ioctl(pipe->fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &req); - - if (pipe->fd) - close(pipe->fd); - - free(pipe); + pipe->funcs->destroy(pipe); } int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value) { - switch (param) { - case FD_DEVICE_ID: - *value = pipe->devinfo.device_id; - return 0; - case FD_GPU_ID: - *value = pipe->devinfo.gpu_id; - return 0; - case FD_GMEM_SIZE: - *value = pipe->devinfo.gmem_sizebytes; - return 0; - default: - ERROR_MSG("invalid param id: %d", param); - return -1; - } + return pipe->funcs->get_param(pipe, param, value); } int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp) { - struct kgsl_device_waittimestamp req = { - .timestamp = timestamp, - .timeout = 5000, - }; - int ret; - - do { - ret = ioctl(pipe->fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP, &req); - } while ((ret == -1) && ((errno == EINTR) || (errno == EAGAIN))); - if (ret) - ERROR_MSG("waittimestamp failed! %d (%s)", ret, strerror(errno)); - else - fd_pipe_process_pending(pipe, timestamp); - return ret; -} - -int fd_pipe_timestamp(struct fd_pipe *pipe, uint32_t *timestamp) -{ - struct kgsl_cmdstream_readtimestamp req = { - .type = KGSL_TIMESTAMP_RETIRED - }; - int ret = ioctl(pipe->fd, IOCTL_KGSL_CMDSTREAM_READTIMESTAMP, &req); - if (ret) { - ERROR_MSG("readtimestamp failed! %d (%s)", - ret, strerror(errno)); - return ret; - } - *timestamp = req.timestamp; - return 0; -} - -/* add buffer to submit list when it is referenced in cmdstream: */ -void fd_pipe_add_submit(struct fd_pipe *pipe, struct fd_bo *bo) -{ - struct list_head *list = &bo->list[pipe->id]; - if (LIST_IS_EMPTY(list)) { - fd_bo_ref(bo); - } else { - list_del(list); - } - list_addtail(list, &pipe->submit_list); -} - -/* prepare buffers on submit list before flush: */ -void fd_pipe_pre_submit(struct fd_pipe *pipe) -{ - struct fd_bo *bo; - - if (pipe->id == FD_PIPE_3D) - return; - - if (!pipe->p3d) - pipe->p3d = fd_pipe_new(pipe->dev, FD_PIPE_3D); - - LIST_FOR_EACH_ENTRY(bo, &pipe->submit_list, list[pipe->id]) { - uint32_t timestamp = fd_bo_get_timestamp(bo); - if (timestamp) - fd_pipe_wait(pipe->p3d, timestamp); - } -} - -/* process buffers on submit list after flush: */ -void fd_pipe_post_submit(struct fd_pipe *pipe, uint32_t timestamp) -{ - struct fd_bo *bo, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &pipe->submit_list, list[pipe->id]) { - struct list_head *list = &bo->list[pipe->id]; - list_del(list); - bo->timestamp[pipe->id] = timestamp; - list_addtail(list, &pipe->pending_list); - - if (pipe->id == FD_PIPE_3D) - fb_bo_set_timestamp(bo, timestamp); - } - - if (!fd_pipe_timestamp(pipe, ×tamp)) - fd_pipe_process_pending(pipe, timestamp); -} - -void fd_pipe_process_pending(struct fd_pipe *pipe, uint32_t timestamp) -{ - struct fd_bo *bo, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &pipe->pending_list, list[pipe->id]) { - struct list_head *list = &bo->list[pipe->id]; - if (bo->timestamp[pipe->id] > timestamp) - return; - list_delinit(list); - bo->timestamp[pipe->id] = 0; - fd_bo_del(bo); - } + return pipe->funcs->wait(pipe, timestamp); } |