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,
{
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;
}
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;
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;
}
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;
}
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:
{
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);
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 =
(*sfc)->height = height;
(*sfc)->stride = stride;
(*sfc)->format = format;
+ (*sfc)->dirty_flag = vigs_dirty_none;
ret = vigs_gem_init(&(*sfc)->gem,
vigs_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;
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);
#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
{
/*
* @{
*/
- bool is_dirty;
+ vigs_dirty_flag dirty_flag;
/*
* @}
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);
/*
* @}
/*
* Bump this whenever driver interface changes.
*/
-#define DRM_VIGS_DRIVER_VERSION 5
+#define DRM_VIGS_DRIVER_VERSION 6
struct drm_vigs_get_protocol_version
{
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;
};
#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)
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