From: Stanislav Vorobiov Date: Thu, 6 Jun 2013 16:48:36 +0000 (+0400) Subject: VIGS: kernel now is surface dirty aware X-Git-Tag: submit/tizen_common/20140905.094502~156 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3a5adc73931b5812b03bbb2d4bf37a2bd635b135;p=sdk%2Femulator%2Femulator-kernel.git VIGS: kernel now is surface dirty aware kernel now knows about dirty state of each surface Change-Id: I7f801fa84f57ee9811fbd79bcb408507439acd62 --- diff --git a/drivers/gpu/drm/vigs/vigs_device.c b/drivers/gpu/drm/vigs/vigs_device.c index f07f4bd3a754..4489ccc511e8 100644 --- a/drivers/gpu/drm/vigs/vigs_device.c +++ b/drivers/gpu/drm/vigs/vigs_device.c @@ -41,12 +41,12 @@ static void vigs_device_mman_vram_to_gpu(void *user_data, struct vigs_gem_object *vigs_gem = bo_to_vigs_gem(bo); struct vigs_surface *vigs_sfc = vigs_gem_to_vigs_surface(vigs_gem); - if (vigs_sfc->is_dirty) { + if (vigs_sfc->dirty_flag == vigs_dirty_vram) { vigs_comm_update_gpu(vigs_dev->comm, vigs_sfc->id, vigs_gem_offset(vigs_gem)); - vigs_sfc->is_dirty = false; } + vigs_sfc->dirty_flag = vigs_dirty_none; } static void vigs_device_mman_gpu_to_vram(void *user_data, @@ -94,8 +94,7 @@ static bool vigs_gem_is_reserved(struct list_head* gem_list, { struct vigs_gem_object *tmp; - list_for_each_entry(tmp, gem_list, list) - { + list_for_each_entry(tmp, gem_list, list) { if (tmp == gem) { return true; } @@ -116,8 +115,13 @@ static int vigs_device_patch_commands(struct vigs_device *vigs_dev, struct vigsp_cmd_batch_header *batch_header = data; struct vigsp_cmd_request_header *request_header = (struct vigsp_cmd_request_header*)(batch_header + 1); - struct vigsp_cmd_update_vram_request *update_vram_request; - struct vigsp_cmd_update_gpu_request *update_gpu_request; + union + { + struct vigsp_cmd_update_vram_request *update_vram; + struct vigsp_cmd_update_gpu_request *update_gpu; + struct vigsp_cmd_copy_request *copy; + struct vigsp_cmd_solid_fill_request *solid_fill; + } request; vigsp_u32 i; struct vigs_surface *sfc; int ret = 0; @@ -144,11 +148,11 @@ static int vigs_device_patch_commands(struct vigs_device *vigs_dev, switch (request_header->cmd) { case vigsp_cmd_update_vram: - update_vram_request = + request.update_vram = (struct vigsp_cmd_update_vram_request*)(request_header + 1); - sfc = vigs_device_reference_surface_unlocked(vigs_dev, update_vram_request->sfc_id); + sfc = vigs_device_reference_surface_unlocked(vigs_dev, request.update_vram->sfc_id); if (!sfc) { - DRM_ERROR("Surface %u not found\n", update_vram_request->sfc_id); + DRM_ERROR("Surface %u not found\n", request.update_vram->sfc_id); ret = -EINVAL; break; } @@ -159,19 +163,20 @@ static int vigs_device_patch_commands(struct vigs_device *vigs_dev, list_add_tail(&sfc->gem.list, gem_list); } if (vigs_gem_in_vram(&sfc->gem)) { - update_vram_request->offset = vigs_gem_offset(&sfc->gem); + request.update_vram->offset = vigs_gem_offset(&sfc->gem); + sfc->dirty_flag = vigs_dirty_none; } else { DRM_DEBUG_DRIVER("Surface %u not in VRAM, ignoring update_vram\n", - update_vram_request->sfc_id); - update_vram_request->sfc_id = 0; + request.update_vram->sfc_id); + request.update_vram->sfc_id = 0; } break; case vigsp_cmd_update_gpu: - update_gpu_request = + request.update_gpu = (struct vigsp_cmd_update_gpu_request*)(request_header + 1); - sfc = vigs_device_reference_surface_unlocked(vigs_dev, update_gpu_request->sfc_id); + sfc = vigs_device_reference_surface_unlocked(vigs_dev, request.update_gpu->sfc_id); if (!sfc) { - DRM_ERROR("Surface %u not found\n", update_gpu_request->sfc_id); + DRM_ERROR("Surface %u not found\n", request.update_gpu->sfc_id); ret = -EINVAL; break; } @@ -182,12 +187,50 @@ static int vigs_device_patch_commands(struct vigs_device *vigs_dev, list_add_tail(&sfc->gem.list, gem_list); } if (vigs_gem_in_vram(&sfc->gem)) { - update_gpu_request->offset = vigs_gem_offset(&sfc->gem); - sfc->is_dirty = false; + request.update_gpu->offset = vigs_gem_offset(&sfc->gem); + sfc->dirty_flag = vigs_dirty_none; } else { DRM_DEBUG_DRIVER("Surface %u not in VRAM, ignoring update_gpu\n", - update_gpu_request->sfc_id); - update_gpu_request->sfc_id = 0; + request.update_gpu->sfc_id); + request.update_gpu->sfc_id = 0; + } + break; + case vigsp_cmd_copy: + request.copy = + (struct vigsp_cmd_copy_request*)(request_header + 1); + sfc = vigs_device_reference_surface_unlocked(vigs_dev, request.copy->dst_id); + if (!sfc) { + DRM_ERROR("Surface %u not found\n", request.copy->dst_id); + ret = -EINVAL; + break; + } + if (vigs_gem_is_reserved(gem_list, &sfc->gem)) { + drm_gem_object_unreference_unlocked(&sfc->gem.base); + } else { + vigs_gem_reserve(&sfc->gem); + list_add_tail(&sfc->gem.list, gem_list); + } + if (vigs_gem_in_vram(&sfc->gem)) { + sfc->dirty_flag = vigs_dirty_gpu; + } + break; + case vigsp_cmd_solid_fill: + request.solid_fill = + (struct vigsp_cmd_solid_fill_request*)(request_header + 1); + sfc = vigs_device_reference_surface_unlocked(vigs_dev, request.solid_fill->sfc_id); + if (!sfc) { + DRM_ERROR("Surface %u not found\n", request.solid_fill->sfc_id); + ret = -EINVAL; + break; + } + if (vigs_gem_is_reserved(gem_list, &sfc->gem)) { + drm_gem_object_unreference_unlocked(&sfc->gem.base); + } else { + vigs_gem_reserve(&sfc->gem); + list_add_tail(&sfc->gem.list, gem_list); + } + if (vigs_gem_in_vram(&sfc->gem)) { + sfc->dirty_flag = vigs_dirty_gpu; } break; default: @@ -206,8 +249,7 @@ static void vigs_device_finish_patch_commands(struct list_head* gem_list) { struct vigs_gem_object *gem, *gem_tmp; - list_for_each_entry_safe(gem, gem_tmp, gem_list, list) - { + list_for_each_entry_safe(gem, gem_tmp, gem_list, list) { list_del(&gem->list); vigs_gem_unreserve(gem); drm_gem_object_unreference_unlocked(&gem->base); diff --git a/drivers/gpu/drm/vigs/vigs_driver.c b/drivers/gpu/drm/vigs/vigs_driver.c index 7caa83724231..c36abaf4ea11 100644 --- a/drivers/gpu/drm/vigs/vigs_driver.c +++ b/drivers/gpu/drm/vigs/vigs_driver.c @@ -43,8 +43,14 @@ static struct drm_ioctl_desc vigs_drm_ioctls[] = DRM_UNLOCKED | DRM_AUTH), DRM_IOCTL_DEF_DRV(VIGS_EXEC, vigs_device_exec_ioctl, DRM_UNLOCKED | DRM_AUTH), - DRM_IOCTL_DEF_DRV(VIGS_SURFACE_SET_DIRTY, vigs_surface_set_dirty_ioctl, - DRM_UNLOCKED | DRM_AUTH), + DRM_IOCTL_DEF_DRV(VIGS_SURFACE_SET_VRAM_DIRTY, vigs_surface_set_vram_dirty_ioctl, + DRM_UNLOCKED | DRM_AUTH), + DRM_IOCTL_DEF_DRV(VIGS_SURFACE_SET_GPU_DIRTY, vigs_surface_set_gpu_dirty_ioctl, + DRM_UNLOCKED | DRM_AUTH), + DRM_IOCTL_DEF_DRV(VIGS_SURFACE_UPDATE_VRAM, vigs_surface_update_vram_ioctl, + DRM_UNLOCKED | DRM_AUTH), + DRM_IOCTL_DEF_DRV(VIGS_SURFACE_UPDATE_GPU, vigs_surface_update_gpu_ioctl, + DRM_UNLOCKED | DRM_AUTH) }; static const struct file_operations vigs_drm_driver_fops = diff --git a/drivers/gpu/drm/vigs/vigs_surface.c b/drivers/gpu/drm/vigs/vigs_surface.c index b03e3b7d0ae6..b3634bb623b0 100644 --- a/drivers/gpu/drm/vigs/vigs_surface.c +++ b/drivers/gpu/drm/vigs/vigs_surface.c @@ -35,6 +35,7 @@ int vigs_surface_create(struct vigs_device *vigs_dev, (*sfc)->height = height; (*sfc)->stride = stride; (*sfc)->format = format; + (*sfc)->dirty_flag = vigs_dirty_none; ret = vigs_gem_init(&(*sfc)->gem, vigs_dev, @@ -150,11 +151,11 @@ int vigs_surface_info_ioctl(struct drm_device *drm_dev, return 0; } -int vigs_surface_set_dirty_ioctl(struct drm_device *drm_dev, - void *data, - struct drm_file *file_priv) +int vigs_surface_set_vram_dirty_ioctl(struct drm_device *drm_dev, + void *data, + struct drm_file *file_priv) { - struct drm_vigs_surface_set_dirty *args = data; + struct drm_vigs_surface_set_vram_dirty *args = data; struct drm_gem_object *gem; struct vigs_gem_object *vigs_gem; struct vigs_surface *sfc; @@ -177,7 +178,126 @@ int vigs_surface_set_dirty_ioctl(struct drm_device *drm_dev, vigs_gem_reserve(&sfc->gem); if (vigs_gem_in_vram(&sfc->gem)) { - sfc->is_dirty = true; + sfc->dirty_flag = vigs_dirty_vram; + } + + vigs_gem_unreserve(&sfc->gem); + + drm_gem_object_unreference_unlocked(gem); + + return 0; +} + +int vigs_surface_set_gpu_dirty_ioctl(struct drm_device *drm_dev, + void *data, + struct drm_file *file_priv) +{ + struct drm_vigs_surface_set_gpu_dirty *args = data; + struct drm_gem_object *gem; + struct vigs_gem_object *vigs_gem; + struct vigs_surface *sfc; + + gem = drm_gem_object_lookup(drm_dev, file_priv, args->handle); + + if (gem == NULL) { + return -ENOENT; + } + + vigs_gem = gem_to_vigs_gem(gem); + + if (vigs_gem->type != VIGS_GEM_TYPE_SURFACE) { + drm_gem_object_unreference_unlocked(gem); + return -ENOENT; + } + + sfc = vigs_gem_to_vigs_surface(vigs_gem); + + vigs_gem_reserve(&sfc->gem); + + if (vigs_gem_in_vram(&sfc->gem)) { + sfc->dirty_flag = vigs_dirty_gpu; + } + + vigs_gem_unreserve(&sfc->gem); + + drm_gem_object_unreference_unlocked(gem); + + return 0; +} + +int vigs_surface_update_vram_ioctl(struct drm_device *drm_dev, + void *data, + struct drm_file *file_priv) +{ + struct vigs_device *vigs_dev = drm_dev->dev_private; + struct drm_vigs_surface_update_vram *args = data; + struct drm_gem_object *gem; + struct vigs_gem_object *vigs_gem; + struct vigs_surface *sfc; + + gem = drm_gem_object_lookup(drm_dev, file_priv, args->handle); + + if (gem == NULL) { + return -ENOENT; + } + + vigs_gem = gem_to_vigs_gem(gem); + + if (vigs_gem->type != VIGS_GEM_TYPE_SURFACE) { + drm_gem_object_unreference_unlocked(gem); + return -ENOENT; + } + + sfc = vigs_gem_to_vigs_surface(vigs_gem); + + vigs_gem_reserve(&sfc->gem); + + if (vigs_gem_in_vram(&sfc->gem) && (sfc->dirty_flag == vigs_dirty_gpu)) { + vigs_comm_update_vram(vigs_dev->comm, + sfc->id, + vigs_gem_offset(vigs_gem)); + sfc->dirty_flag = vigs_dirty_none; + } + + vigs_gem_unreserve(&sfc->gem); + + drm_gem_object_unreference_unlocked(gem); + + return 0; +} + +int vigs_surface_update_gpu_ioctl(struct drm_device *drm_dev, + void *data, + struct drm_file *file_priv) +{ + struct vigs_device *vigs_dev = drm_dev->dev_private; + struct drm_vigs_surface_update_gpu *args = data; + struct drm_gem_object *gem; + struct vigs_gem_object *vigs_gem; + struct vigs_surface *sfc; + + gem = drm_gem_object_lookup(drm_dev, file_priv, args->handle); + + if (gem == NULL) { + return -ENOENT; + } + + vigs_gem = gem_to_vigs_gem(gem); + + if (vigs_gem->type != VIGS_GEM_TYPE_SURFACE) { + drm_gem_object_unreference_unlocked(gem); + return -ENOENT; + } + + sfc = vigs_gem_to_vigs_surface(vigs_gem); + + vigs_gem_reserve(&sfc->gem); + + if (vigs_gem_in_vram(&sfc->gem)) { + vigs_comm_update_gpu(vigs_dev->comm, + sfc->id, + vigs_gem_offset(vigs_gem)); + sfc->dirty_flag = vigs_dirty_none; } vigs_gem_unreserve(&sfc->gem); diff --git a/drivers/gpu/drm/vigs/vigs_surface.h b/drivers/gpu/drm/vigs/vigs_surface.h index 6a81fdc57da7..25ad8dac464a 100644 --- a/drivers/gpu/drm/vigs/vigs_surface.h +++ b/drivers/gpu/drm/vigs/vigs_surface.h @@ -5,6 +5,13 @@ #include "vigs_protocol.h" #include "vigs_gem.h" +typedef enum +{ + vigs_dirty_none = 0, + vigs_dirty_vram = 1, + vigs_dirty_gpu = 2 +} vigs_dirty_flag; + struct vigs_surface { /* @@ -24,7 +31,7 @@ struct vigs_surface * @{ */ - bool is_dirty; + vigs_dirty_flag dirty_flag; /* * @} @@ -56,9 +63,21 @@ int vigs_surface_info_ioctl(struct drm_device *drm_dev, void *data, struct drm_file *file_priv); -int vigs_surface_set_dirty_ioctl(struct drm_device *drm_dev, - void *data, - struct drm_file *file_priv); +int vigs_surface_set_vram_dirty_ioctl(struct drm_device *drm_dev, + void *data, + struct drm_file *file_priv); + +int vigs_surface_set_gpu_dirty_ioctl(struct drm_device *drm_dev, + void *data, + struct drm_file *file_priv); + +int vigs_surface_update_vram_ioctl(struct drm_device *drm_dev, + void *data, + struct drm_file *file_priv); + +int vigs_surface_update_gpu_ioctl(struct drm_device *drm_dev, + void *data, + struct drm_file *file_priv); /* * @} diff --git a/include/drm/vigs_drm.h b/include/drm/vigs_drm.h index 10427f34eb86..878384149a9d 100644 --- a/include/drm/vigs_drm.h +++ b/include/drm/vigs_drm.h @@ -8,7 +8,7 @@ /* * Bump this whenever driver interface changes. */ -#define DRM_VIGS_DRIVER_VERSION 5 +#define DRM_VIGS_DRIVER_VERSION 6 struct drm_vigs_get_protocol_version { @@ -51,7 +51,22 @@ struct drm_vigs_exec uint32_t handle; }; -struct drm_vigs_surface_set_dirty +struct drm_vigs_surface_set_vram_dirty +{ + uint32_t handle; +}; + +struct drm_vigs_surface_set_gpu_dirty +{ + uint32_t handle; +}; + +struct drm_vigs_surface_update_vram +{ + uint32_t handle; +}; + +struct drm_vigs_surface_update_gpu { uint32_t handle; }; @@ -61,7 +76,10 @@ struct drm_vigs_surface_set_dirty #define DRM_VIGS_CREATE_EXECBUFFER 0x02 #define DRM_VIGS_SURFACE_INFO 0x03 #define DRM_VIGS_EXEC 0x04 -#define DRM_VIGS_SURFACE_SET_DIRTY 0x05 +#define DRM_VIGS_SURFACE_SET_VRAM_DIRTY 0x05 +#define DRM_VIGS_SURFACE_SET_GPU_DIRTY 0x06 +#define DRM_VIGS_SURFACE_UPDATE_VRAM 0x07 +#define DRM_VIGS_SURFACE_UPDATE_GPU 0x08 #define DRM_IOCTL_VIGS_GET_PROTOCOL_VERSION DRM_IOR(DRM_COMMAND_BASE + \ DRM_VIGS_GET_PROTOCOL_VERSION, struct drm_vigs_get_protocol_version) @@ -73,7 +91,13 @@ struct drm_vigs_surface_set_dirty DRM_VIGS_SURFACE_INFO, struct drm_vigs_surface_info) #define DRM_IOCTL_VIGS_EXEC DRM_IOW(DRM_COMMAND_BASE + \ DRM_VIGS_EXEC, struct drm_vigs_exec) -#define DRM_IOCTL_VIGS_SURFACE_SET_DIRTY DRM_IOW(DRM_COMMAND_BASE + \ - DRM_VIGS_SURFACE_SET_DIRTY, struct drm_vigs_surface_set_dirty) +#define DRM_IOCTL_VIGS_SURFACE_SET_VRAM_DIRTY DRM_IOW(DRM_COMMAND_BASE + \ + DRM_VIGS_SURFACE_SET_VRAM_DIRTY, struct drm_vigs_surface_set_vram_dirty) +#define DRM_IOCTL_VIGS_SURFACE_SET_GPU_DIRTY DRM_IOW(DRM_COMMAND_BASE + \ + DRM_VIGS_SURFACE_SET_GPU_DIRTY, struct drm_vigs_surface_set_gpu_dirty) +#define DRM_IOCTL_VIGS_SURFACE_UPDATE_VRAM DRM_IOW(DRM_COMMAND_BASE + \ + DRM_VIGS_SURFACE_UPDATE_VRAM, struct drm_vigs_surface_update_vram) +#define DRM_IOCTL_VIGS_SURFACE_UPDATE_GPU DRM_IOW(DRM_COMMAND_BASE + \ + DRM_VIGS_SURFACE_UPDATE_GPU, struct drm_vigs_surface_update_gpu) #endif