From: Stanislav Vorobiov Date: Thu, 27 Jun 2013 14:24:28 +0000 (+0400) Subject: VIGS: Automatically update VRAM when setting new root surface X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=929a319f70138e99f7e7ad3c8cb82766e99025e1;p=sdk%2Femulator%2Femulator-kernel.git VIGS: Automatically update VRAM when setting new root surface When we set new root surface (for example, as part of pageflip) we should check if that surface is GPU dirty and if it is - update VRAM. If we don't do this we might flip stuff without QEMU display being updated --- diff --git a/drivers/gpu/drm/vigs/vigs_comm.c b/drivers/gpu/drm/vigs/vigs_comm.c index 967ac3d8f30f..cc5685b6dbd0 100644 --- a/drivers/gpu/drm/vigs/vigs_comm.c +++ b/drivers/gpu/drm/vigs/vigs_comm.c @@ -4,31 +4,21 @@ #include "vigs_regs.h" #include -static int vigs_comm_prepare(struct vigs_comm *comm, - vigsp_cmd cmd, - unsigned long request_size, - unsigned long response_size, - void **request, - void **response) +static int vigs_comm_alloc(struct vigs_comm *comm, + unsigned long size, + void **ptr) { int ret; - void *ptr; - struct vigsp_cmd_batch_header *batch_header; - struct vigsp_cmd_request_header *request_header; - unsigned long total_size = sizeof(*batch_header) + - sizeof(*request_header) + - request_size + - sizeof(struct vigsp_cmd_response_header) + - response_size; - if (!comm->execbuffer || (vigs_gem_size(&comm->execbuffer->gem) < total_size)) { + if (!comm->execbuffer || + (vigs_gem_size(&comm->execbuffer->gem) < size)) { if (comm->execbuffer) { drm_gem_object_unreference_unlocked(&comm->execbuffer->gem.base); comm->execbuffer = NULL; } ret = vigs_execbuffer_create(comm->vigs_dev, - total_size, + size, true, &comm->execbuffer); @@ -53,9 +43,36 @@ static int vigs_comm_prepare(struct vigs_comm *comm, } } - ptr = comm->execbuffer->gem.kptr; + *ptr = comm->execbuffer->gem.kptr; + + memset(*ptr, 0, vigs_gem_size(&comm->execbuffer->gem)); + + return 0; +} + +static int vigs_comm_prepare(struct vigs_comm *comm, + vigsp_cmd cmd, + unsigned long request_size, + unsigned long response_size, + void **request, + void **response) +{ + int ret; + void *ptr; + struct vigsp_cmd_batch_header *batch_header; + struct vigsp_cmd_request_header *request_header; - memset(ptr, 0, vigs_gem_size(&comm->execbuffer->gem)); + ret = vigs_comm_alloc(comm, + sizeof(*batch_header) + + sizeof(*request_header) + + request_size + + sizeof(struct vigsp_cmd_response_header) + + response_size, + &ptr); + + if (ret != 0) { + return ret; + } batch_header = ptr; request_header = (struct vigsp_cmd_request_header*)(batch_header + 1); @@ -89,9 +106,16 @@ static int vigs_comm_exec_internal(struct vigs_comm *comm) struct vigsp_cmd_batch_header *batch_header = comm->execbuffer->gem.kptr; struct vigsp_cmd_request_header *request_header = (struct vigsp_cmd_request_header*)(batch_header + 1); - struct vigsp_cmd_response_header *response_header = - (struct vigsp_cmd_response_header*)((u8*)(request_header + 1) + - request_header->size); + struct vigsp_cmd_response_header *response_header; + vigsp_u32 i; + + for (i = 0; i < batch_header->num_requests; ++i) { + request_header = + (struct vigsp_cmd_request_header*)((uint8_t*)(request_header + 1) + + request_header->size); + } + + response_header = (struct vigsp_cmd_response_header*)request_header; vigs_comm_exec_locked(comm, comm->execbuffer); @@ -302,25 +326,63 @@ int vigs_comm_destroy_surface(struct vigs_comm *comm, vigsp_surface_id id) int vigs_comm_set_root_surface(struct vigs_comm *comm, vigsp_surface_id id, - vigsp_offset offset) + vigsp_offset offset, + bool update_vram) { int ret; - struct vigsp_cmd_set_root_surface_request *request; + struct vigsp_cmd_batch_header *batch_header; + struct vigsp_cmd_request_header *update_vram_header = NULL; + struct vigsp_cmd_update_vram_request *update_vram_request = NULL; + struct vigsp_cmd_request_header *set_root_surface_header; + struct vigsp_cmd_set_root_surface_request *set_root_surface_request; + void *ptr; DRM_DEBUG_DRIVER("id = %u, offset = %u\n", id, offset); mutex_lock(&comm->mutex); - ret = vigs_comm_prepare(comm, - vigsp_cmd_set_root_surface, - sizeof(*request), - 0, - (void**)&request, - NULL); + ret = vigs_comm_alloc(comm, + sizeof(*batch_header) + + (update_vram ? sizeof(*update_vram_header) + + sizeof(*update_vram_request) + : 0) + + sizeof(*set_root_surface_header) + + sizeof(*set_root_surface_request) + + sizeof(struct vigsp_cmd_response_header), + &ptr); if (ret == 0) { - request->id = id; - request->offset = offset; + batch_header = ptr; + ptr = batch_header + 1; + + if (update_vram) { + update_vram_header = ptr; + ptr = update_vram_header + 1; + update_vram_request = ptr; + ptr = update_vram_request + 1; + } + + set_root_surface_header = ptr; + ptr = set_root_surface_header + 1; + set_root_surface_request = ptr; + + if (update_vram) { + batch_header->num_requests = 2; + + update_vram_header->cmd = vigsp_cmd_update_vram; + update_vram_header->size = sizeof(*update_vram_request); + + update_vram_request->sfc_id = id; + update_vram_request->offset = offset; + } else { + batch_header->num_requests = 1; + } + + set_root_surface_header->cmd = vigsp_cmd_set_root_surface; + set_root_surface_header->size = sizeof(*set_root_surface_request); + + set_root_surface_request->id = id; + set_root_surface_request->offset = offset; ret = vigs_comm_exec_internal(comm); } diff --git a/drivers/gpu/drm/vigs/vigs_comm.h b/drivers/gpu/drm/vigs/vigs_comm.h index 5372696fb3e0..f88aac751e19 100644 --- a/drivers/gpu/drm/vigs/vigs_comm.h +++ b/drivers/gpu/drm/vigs/vigs_comm.h @@ -51,7 +51,8 @@ int vigs_comm_destroy_surface(struct vigs_comm *comm, vigsp_surface_id id); int vigs_comm_set_root_surface(struct vigs_comm *comm, vigsp_surface_id id, - vigsp_offset offset); + vigsp_offset offset, + bool update_vram); int vigs_comm_update_vram(struct vigs_comm *comm, vigsp_surface_id id, diff --git a/drivers/gpu/drm/vigs/vigs_crtc.c b/drivers/gpu/drm/vigs/vigs_crtc.c index 581f6870934d..8c985d07132c 100644 --- a/drivers/gpu/drm/vigs/vigs_crtc.c +++ b/drivers/gpu/drm/vigs/vigs_crtc.c @@ -40,9 +40,14 @@ static int vigs_crtc_update(struct drm_crtc *crtc, return ret; } + vigs_gem_reserve(&vigs_fb->fb_sfc->gem); + ret = vigs_comm_set_root_surface(vigs_dev->comm, vigs_fb->fb_sfc->id, - vigs_gem_offset(&vigs_fb->fb_sfc->gem)); + vigs_gem_offset(&vigs_fb->fb_sfc->gem), + vigs_fb->fb_sfc->is_gpu_dirty); + + vigs_gem_unreserve(&vigs_fb->fb_sfc->gem); if (ret != 0) { vigs_framebuffer_unpin(vigs_fb); @@ -173,7 +178,7 @@ static void vigs_crtc_disable(struct drm_crtc *crtc) return; } - vigs_comm_set_root_surface(vigs_dev->comm, 0, 0); + vigs_comm_set_root_surface(vigs_dev->comm, 0, 0, false); vigs_framebuffer_unpin(fb_to_vigs_fb(crtc->fb)); }