Adding some folks on CC for broader distribution.
On Tue, Jan 9, 2018 at 3:52 PM, Lepton Wu <lep...@chromium.org> wrote: > Gentle ping. Thanks. > > On Wed, Dec 27, 2017 at 11:35 PM, Lepton Wu <lep...@chromium.org> wrote: >> v2: address comments from Tomasz Figa >> a) Add more check for plane size. >> b) Avoid duplicated mapping and leaked mapping. >> c) Other minor changes. >> >> Signed-off-by: Lepton Wu <lep...@chromium.org> >> >> Change-Id: I0863f522976cc8863d6e95492d9346df35c066ec >> --- >> src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 179 >> +++++++++++++++------- >> 1 file changed, 126 insertions(+), 53 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..69c05197081 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,20 +59,29 @@ >> #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; >> void *mapped; >> + void *ro_mapped; >> >> int ref_count; >> struct list_head link; >> + struct list_head planes; >> }; >> >> struct kms_sw_winsys >> @@ -83,10 +92,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 +114,42 @@ 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, >> + enum pipe_format format, >> + unsigned width, unsigned height, >> + unsigned stride, unsigned offset) { >> + struct kms_sw_plane * tmp, * plane = NULL; >> + if (offset + util_format_get_2d_size(format, stride, height) > >> + kms_sw_dt->size) { >> + DEBUG_PRINT("KMS-DEBUG: plane too big. format: %d stride: %d height: >> %d " >> + "offset: %d size:%d\n", format, stride, height, 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 +169,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 +182,19 @@ 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; >> + struct kms_sw_plane* plane = get_plane(kms_sw_dt, format, width, height, >> + create_req.pitch, 0); >> + if (plane == 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 *) plane; >> free_bo: >> memset(&destroy_req, 0, sizeof destroy_req); >> destroy_req.handle = create_req.handle; >> @@ -163,13 +209,19 @@ 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_plane *plane = kms_sw_plane(dt); >> + struct kms_sw_displaytarget *kms_sw_dt = plane->dt; >> struct drm_mode_destroy_dumb destroy_req; >> >> kms_sw_dt->ref_count --; >> if (kms_sw_dt->ref_count > 0) >> return; >> >> + if (kms_sw_dt->ro_mapped) >> + munmap(kms_sw_dt->ro_mapped, kms_sw_dt->size); >> + if (kms_sw_dt->mapped) >> + munmap(kms_sw_dt->mapped, kms_sw_dt->size); >> + >> memset(&destroy_req, 0, sizeof destroy_req); >> destroy_req.handle = kms_sw_dt->handle; >> drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_req); >> @@ -178,6 +230,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 * tmp; >> + LIST_FOR_EACH_ENTRY_SAFE(plane, tmp, &kms_sw_dt->planes, link) { >> + FREE(plane); >> + } >> FREE(kms_sw_dt); >> } >> >> @@ -187,7 +243,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 *plane = kms_sw_plane(dt); >> + struct kms_sw_displaytarget *kms_sw_dt = plane->dt; >> struct drm_mode_map_dumb map_req; >> int prot, ret; >> >> @@ -198,16 +255,20 @@ kms_sw_displaytarget_map(struct sw_winsys *ws, >> return NULL; >> >> prot = (flags == PIPE_TRANSFER_READ) ? PROT_READ : (PROT_READ | >> PROT_WRITE); >> - kms_sw_dt->mapped = mmap(0, kms_sw_dt->size, prot, MAP_SHARED, >> - kms_sw->fd, map_req.offset); >> - >> - if (kms_sw_dt->mapped == MAP_FAILED) >> - return NULL; >> + void **ptr = (flags == PIPE_TRANSFER_READ) ? &kms_sw_dt->ro_mapped : >> &kms_sw_dt->mapped; >> + if (*ptr == NULL) { >> + void * tmp = mmap(0, kms_sw_dt->size, prot, MAP_SHARED, >> + kms_sw->fd, map_req.offset); >> + if (tmp == MAP_FAILED) >> + return NULL; >> + *ptr = tmp; >> + } >> >> - 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, *ptr, >> + plane->width, plane->height); >> >> - return kms_sw_dt->mapped; >> + return *ptr + plane->offset; >> } >> >> static struct kms_sw_displaytarget * >> @@ -230,10 +291,11 @@ 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, >> + enum pipe_format format, >> unsigned width, unsigned height, >> - unsigned stride) >> + unsigned stride, unsigned offset) >> { >> uint32_t handle = -1; >> struct kms_sw_displaytarget * kms_sw_dt; >> @@ -245,13 +307,19 @@ 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; >> + struct kms_sw_plane * plane = NULL; >> + if (kms_sw_dt) { >> + plane = get_plane(kms_sw_dt, format, width, height, stride, offset); >> + if (plane == NULL) >> + kms_sw_dt->ref_count --; >> + return plane; >> + } >> >> 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,27 +328,27 @@ 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); >> + plane = get_plane(kms_sw_dt, format, width, height, stride, offset); >> + if (plane == NULL) { >> + FREE(kms_sw_dt); >> + return NULL; >> + } >> >> list_add(&kms_sw_dt->link, &kms_sw->bo_list); >> >> - return kms_sw_dt; >> + return plane; >> } >> >> 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_plane * plane = kms_sw_plane(dt); >> + struct kms_sw_displaytarget *kms_sw_dt = plane->dt; >> >> - DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n", >> kms_sw_dt->handle, kms_sw_dt->mapped); >> - >> - munmap(kms_sw_dt->mapped, kms_sw_dt->size); >> - kms_sw_dt->mapped = NULL; >> + DEBUG_PRINT("KMS-DEBUG: ignore unmap buffer %u \n", kms_sw_dt->handle); >> } >> >> static struct sw_displaytarget * >> @@ -291,30 +359,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->format, >> 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 --; >> } >> /* fallthrough */ >> default: >> @@ -331,19 +403,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 *plane = kms_sw_plane(dt); >> + struct kms_sw_displaytarget *kms_sw_dt = plane->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 = plane->stride; >> + whandle->offset = plane->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 = plane->stride; >> + whandle->offset = plane->offset; >> return TRUE; >> } >> /* fallthrough */ >> -- >> 2.15.1.620.gb9897f4670-goog >> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev