From: Lepton Wu <lep...@chromium.org> Signed-off-by: Lepton Wu <lep...@chromium.org>
Change-Id: I0863f522976cc8863d6e95492d9346df35c066ec --- src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 150 +++++++++++++++------- 1 file changed, 106 insertions(+), 44 deletions(-) diff --git a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c index 22e1c936ac5..514298aea4e 100644 --- a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c +++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c @@ -59,13 +59,20 @@ #define DEBUG_PRINT(msg, ...) #endif +struct kms_sw_displaytarget; -struct kms_sw_displaytarget -{ - enum pipe_format format; +struct kms_sw_plane { unsigned width; unsigned height; unsigned stride; + unsigned offset; + struct kms_sw_displaytarget* dt; + struct list_head link; +}; + +struct kms_sw_displaytarget +{ + enum pipe_format format; unsigned size; uint32_t handle; @@ -73,6 +80,7 @@ struct kms_sw_displaytarget int ref_count; struct list_head link; + struct list_head planes; }; struct kms_sw_winsys @@ -83,10 +91,10 @@ struct kms_sw_winsys struct list_head bo_list; }; -static inline struct kms_sw_displaytarget * -kms_sw_displaytarget( struct sw_displaytarget *dt ) +static inline struct kms_sw_plane * +kms_sw_plane( struct sw_displaytarget *dt ) { - return (struct kms_sw_displaytarget *)dt; + return (struct kms_sw_plane *)dt; } static inline struct kms_sw_winsys * @@ -105,6 +113,39 @@ kms_sw_is_displaytarget_format_supported( struct sw_winsys *ws, return TRUE; } +static struct kms_sw_plane *get_plane(struct kms_sw_displaytarget *kms_sw_dt, + unsigned width, unsigned height, + unsigned stride, unsigned offset) { + struct kms_sw_plane * tmp, * plane = NULL; + if (offset > kms_sw_dt->size) { + DEBUG_PRINT("KMS-DEBUG: offset %d bigger then %d\n", + offset, kms_sw_dt->size); + return NULL; + } + LIST_FOR_EACH_ENTRY(tmp, &kms_sw_dt->planes, link) { + if (tmp->offset == offset) { + plane = tmp; + break; + } + } + if (plane) { + assert(plane->width == width); + assert(plane->height == height); + assert(plane->stride == stride); + assert(plane->dt == kms_sw_dt); + } else { + plane = CALLOC_STRUCT(kms_sw_plane); + if (plane == NULL) return NULL; + plane->width = width; + plane->height = height; + plane->stride = stride; + plane->offset = offset; + plane->dt = kms_sw_dt; + list_add(&plane->link, &kms_sw_dt->planes); + } + return plane; +} + static struct sw_displaytarget * kms_sw_displaytarget_create(struct sw_winsys *ws, unsigned tex_usage, @@ -124,11 +165,10 @@ kms_sw_displaytarget_create(struct sw_winsys *ws, if (!kms_sw_dt) goto no_dt; + list_inithead(&kms_sw_dt->planes); kms_sw_dt->ref_count = 1; kms_sw_dt->format = format; - kms_sw_dt->width = width; - kms_sw_dt->height = height; memset(&create_req, 0, sizeof(create_req)); create_req.bpp = 32; @@ -138,17 +178,20 @@ kms_sw_displaytarget_create(struct sw_winsys *ws, if (ret) goto free_bo; - kms_sw_dt->stride = create_req.pitch; kms_sw_dt->size = create_req.size; kms_sw_dt->handle = create_req.handle; + if (get_plane(kms_sw_dt, width, height, create_req.pitch, create_req.size) + == NULL) + goto free_bo; list_add(&kms_sw_dt->link, &kms_sw->bo_list); DEBUG_PRINT("KMS-DEBUG: created buffer %u (size %u)\n", kms_sw_dt->handle, kms_sw_dt->size); - *stride = kms_sw_dt->stride; - return (struct sw_displaytarget *)kms_sw_dt; - + *stride = create_req.pitch; + return (struct sw_displaytarget *) list_first_entry(&kms_sw_dt->planes, + struct kms_sw_plane, + link); free_bo: memset(&destroy_req, 0, sizeof destroy_req); destroy_req.handle = create_req.handle; @@ -163,7 +206,7 @@ kms_sw_displaytarget_destroy(struct sw_winsys *ws, struct sw_displaytarget *dt) { struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws); - struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); + struct kms_sw_displaytarget *kms_sw_dt = kms_sw_plane(dt)->dt; struct drm_mode_destroy_dumb destroy_req; kms_sw_dt->ref_count --; @@ -178,6 +221,10 @@ kms_sw_displaytarget_destroy(struct sw_winsys *ws, DEBUG_PRINT("KMS-DEBUG: destroyed buffer %u\n", kms_sw_dt->handle); + struct kms_sw_plane * plane, * tmp; + LIST_FOR_EACH_ENTRY_SAFE(plane, tmp, &kms_sw_dt->planes, link) { + FREE(plane); + } FREE(kms_sw_dt); } @@ -187,7 +234,8 @@ kms_sw_displaytarget_map(struct sw_winsys *ws, unsigned flags) { struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws); - struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); + struct kms_sw_plane *kms_sw_pl = kms_sw_plane(dt); + struct kms_sw_displaytarget *kms_sw_dt = kms_sw_pl->dt; struct drm_mode_map_dumb map_req; int prot, ret; @@ -204,10 +252,11 @@ kms_sw_displaytarget_map(struct sw_winsys *ws, if (kms_sw_dt->mapped == MAP_FAILED) return NULL; - DEBUG_PRINT("KMS-DEBUG: mapped buffer %u (size %u) at %p\n", - kms_sw_dt->handle, kms_sw_dt->size, kms_sw_dt->mapped); + DEBUG_PRINT("KMS-DEBUG: mapped buffer %u (size %u) at %p %dx%d \n", + kms_sw_dt->handle, kms_sw_dt->size, kms_sw_dt->mapped, + kms_sw_pl->width, kms_sw_pl->height); - return kms_sw_dt->mapped; + return kms_sw_dt->mapped + kms_sw_pl->offset; } static struct kms_sw_displaytarget * @@ -230,10 +279,10 @@ kms_sw_displaytarget_find_and_ref(struct kms_sw_winsys *kms_sw, return NULL; } -static struct kms_sw_displaytarget * +static struct kms_sw_plane * kms_sw_displaytarget_add_from_prime(struct kms_sw_winsys *kms_sw, int fd, unsigned width, unsigned height, - unsigned stride) + unsigned stride, unsigned offset) { uint32_t handle = -1; struct kms_sw_displaytarget * kms_sw_dt; @@ -245,13 +294,20 @@ kms_sw_displaytarget_add_from_prime(struct kms_sw_winsys *kms_sw, int fd, return NULL; kms_sw_dt = kms_sw_displaytarget_find_and_ref(kms_sw, handle); - if (kms_sw_dt) - return kms_sw_dt; + if (kms_sw_dt) { + struct kms_sw_plane * pl = get_plane(kms_sw_dt, width, height, + stride, offset); + if (pl == NULL) { + kms_sw_dt->ref_count --; + } + return pl; + } kms_sw_dt = CALLOC_STRUCT(kms_sw_displaytarget); if (!kms_sw_dt) return NULL; + list_inithead(&kms_sw_dt->planes); off_t lseek_ret = lseek(fd, 0, SEEK_END); if (lseek_ret == -1) { FREE(kms_sw_dt); @@ -260,22 +316,23 @@ kms_sw_displaytarget_add_from_prime(struct kms_sw_winsys *kms_sw, int fd, kms_sw_dt->size = lseek_ret; kms_sw_dt->ref_count = 1; kms_sw_dt->handle = handle; - kms_sw_dt->width = width; - kms_sw_dt->height = height; - kms_sw_dt->stride = stride; lseek(fd, 0, SEEK_SET); + if (get_plane(kms_sw_dt, width, height, stride, offset) == NULL) { + FREE(kms_sw_dt); + return NULL; + } list_add(&kms_sw_dt->link, &kms_sw->bo_list); - return kms_sw_dt; + return list_first_entry(&kms_sw_dt->planes, struct kms_sw_plane, link); } static void kms_sw_displaytarget_unmap(struct sw_winsys *ws, struct sw_displaytarget *dt) { - struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); + struct kms_sw_displaytarget *kms_sw_dt = kms_sw_plane(dt)->dt; DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n", kms_sw_dt->handle, kms_sw_dt->mapped); @@ -291,30 +348,34 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws, { struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws); struct kms_sw_displaytarget *kms_sw_dt; + struct kms_sw_plane *kms_sw_pl; assert(whandle->type == DRM_API_HANDLE_TYPE_KMS || whandle->type == DRM_API_HANDLE_TYPE_FD); - if (whandle->offset != 0) { - DEBUG_PRINT("KMS-DEBUG: attempt to import unsupported winsys offset %d\n", - whandle->offset); - return NULL; - } - switch(whandle->type) { case DRM_API_HANDLE_TYPE_FD: - kms_sw_dt = kms_sw_displaytarget_add_from_prime(kms_sw, whandle->handle, + kms_sw_pl = kms_sw_displaytarget_add_from_prime(kms_sw, whandle->handle, templ->width0, templ->height0, - whandle->stride); - if (kms_sw_dt) - *stride = kms_sw_dt->stride; - return (struct sw_displaytarget *)kms_sw_dt; + whandle->stride, + whandle->offset); + if (kms_sw_pl) { + *stride = kms_sw_pl->stride; + } + return (struct sw_displaytarget *)kms_sw_pl; case DRM_API_HANDLE_TYPE_KMS: kms_sw_dt = kms_sw_displaytarget_find_and_ref(kms_sw, whandle->handle); if (kms_sw_dt) { - *stride = kms_sw_dt->stride; - return (struct sw_displaytarget *)kms_sw_dt; + struct kms_sw_plane * plane; + LIST_FOR_EACH_ENTRY(plane, &kms_sw_dt->planes, link) { + if (whandle->offset == plane->offset) { + *stride = plane->stride; + return (struct sw_displaytarget *)plane; + } + } + kms_sw_dt->ref_count --; + return NULL; } /* fallthrough */ default: @@ -331,19 +392,20 @@ kms_sw_displaytarget_get_handle(struct sw_winsys *winsys, struct winsys_handle *whandle) { struct kms_sw_winsys *kms_sw = kms_sw_winsys(winsys); - struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); + struct kms_sw_plane *kms_sw_pl = kms_sw_plane(dt); + struct kms_sw_displaytarget *kms_sw_dt = kms_sw_pl->dt; switch(whandle->type) { case DRM_API_HANDLE_TYPE_KMS: whandle->handle = kms_sw_dt->handle; - whandle->stride = kms_sw_dt->stride; - whandle->offset = 0; + whandle->stride = kms_sw_pl->stride; + whandle->offset = kms_sw_pl->offset; return TRUE; case DRM_API_HANDLE_TYPE_FD: if (!drmPrimeHandleToFD(kms_sw->fd, kms_sw_dt->handle, DRM_CLOEXEC, (int*)&whandle->handle)) { - whandle->stride = kms_sw_dt->stride; - whandle->offset = 0; + whandle->stride = kms_sw_pl->stride; + whandle->offset = kms_sw_pl->offset; return TRUE; } /* fallthrough */ -- 2.13.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev