Hi Thomas, On Tue, Aug 03, 2021 at 02:59:18PM +0200, Thomas Zimmermann wrote: > Add an additional argument to drm_gem_fb_vmap() to return each BO's > mapping adjusted by the rsp offset. Update all callers. rsp? respective? > > The newly returned values point to the first by of the data stored by => byte > in the framebuffer BOs. Drivers that access the BO data should use > it. > > Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> Reviewed-by: Sam Ravnborg <sam@xxxxxxxxxxxx> > --- > drivers/gpu/drm/drm_gem_atomic_helper.c | 2 +- > drivers/gpu/drm/drm_gem_framebuffer_helper.c | 17 ++++++++++++++++- > drivers/gpu/drm/gud/gud_pipe.c | 2 +- > drivers/gpu/drm/vkms/vkms_writeback.c | 2 +- > include/drm/drm_gem_atomic_helper.h | 8 ++++++++ > include/drm/drm_gem_framebuffer_helper.h | 3 ++- > 6 files changed, 29 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c > index b1cc19e47165..8410ec3c5db0 100644 > --- a/drivers/gpu/drm/drm_gem_atomic_helper.c > +++ b/drivers/gpu/drm/drm_gem_atomic_helper.c > @@ -339,7 +339,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p > if (ret) > return ret; > > - return drm_gem_fb_vmap(fb, shadow_plane_state->map); > + return drm_gem_fb_vmap(fb, shadow_plane_state->map, shadow_plane_state->data); > } > EXPORT_SYMBOL(drm_gem_prepare_shadow_fb); > > diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c > index 02928607a716..7f2bbe4f0053 100644 > --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c > +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c > @@ -316,19 +316,25 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty); > * drm_gem_fb_vmap - maps all framebuffer BOs into kernel address space > * @fb: the framebuffer > * @map: returns the mapping's address for each BO > + * @data: returns the data address for each BO, can be NULL > * > * This function maps all buffer objects of the given framebuffer into > * kernel address space and stores them in struct dma_buf_map. If the > * mapping operation fails for one of the BOs, the function unmaps the > * already established mappings automatically. > * > + * Callers that want to access a BO's stored data should pass @data. > + * The argument returns the addresses of the data stored in each BO. This > + * is different from @map if the framebuffer's offsets field is non-zero. > + * > * See drm_gem_fb_vunmap() for unmapping. > * > * Returns: > * 0 on success, or a negative errno code otherwise. > */ > int drm_gem_fb_vmap(struct drm_framebuffer *fb, > - struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]) > + struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES], > + struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]) > { > struct drm_gem_object *obj; > unsigned int i; > @@ -345,6 +351,15 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, > goto err_drm_gem_vunmap; > } > > + if (data) { > + for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) { > + memcpy(&data[i], &map[i], sizeof(data[i])); > + if (dma_buf_map_is_null(&data[i])) > + continue; > + dma_buf_map_incr(&data[i], fb->offsets[i]); > + } > + } > + > return 0; > > err_drm_gem_vunmap: > diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c > index 7e009f562b30..6270a1a32a65 100644 > --- a/drivers/gpu/drm/gud/gud_pipe.c > +++ b/drivers/gpu/drm/gud/gud_pipe.c > @@ -162,7 +162,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, > if (len > gdrm->bulk_len) > return -E2BIG; > > - ret = drm_gem_fb_vmap(fb, map); > + ret = drm_gem_fb_vmap(fb, map, NULL); > if (ret) > return ret; > > diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c > index 425b6c6b8cad..3a8e2ed93e7c 100644 > --- a/drivers/gpu/drm/vkms/vkms_writeback.c > +++ b/drivers/gpu/drm/vkms/vkms_writeback.c > @@ -75,7 +75,7 @@ static int vkms_wb_prepare_job(struct drm_writeback_connector *wb_connector, > if (!vkmsjob) > return -ENOMEM; > > - ret = drm_gem_fb_vmap(job->fb, vkmsjob->map); > + ret = drm_gem_fb_vmap(job->fb, vkmsjob->map, NULL); > if (ret) { > DRM_ERROR("vmap failed: %d\n", ret); > goto err_kfree; > diff --git a/include/drm/drm_gem_atomic_helper.h b/include/drm/drm_gem_atomic_helper.h > index f9f8b6f0494a..48222a107873 100644 > --- a/include/drm/drm_gem_atomic_helper.h > +++ b/include/drm/drm_gem_atomic_helper.h > @@ -42,6 +42,14 @@ struct drm_shadow_plane_state { > * prepare_fb callback and removed in the cleanup_fb callback. > */ > struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; > + > + /** > + * @data: Address of each framebuffer BO's data > + * > + * The address of the data stored in each mapping. This is different > + * for framebuffers with non-zero offset fields. > + */ > + struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]; > }; > > /** > diff --git a/include/drm/drm_gem_framebuffer_helper.h b/include/drm/drm_gem_framebuffer_helper.h > index ff2024dd7b77..905727719ead 100644 > --- a/include/drm/drm_gem_framebuffer_helper.h > +++ b/include/drm/drm_gem_framebuffer_helper.h > @@ -40,7 +40,8 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file, > const struct drm_mode_fb_cmd2 *mode_cmd); > > int drm_gem_fb_vmap(struct drm_framebuffer *fb, > - struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]); > + struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES], > + struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]); > void drm_gem_fb_vunmap(struct drm_framebuffer *fb, > struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]); > int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir); > -- > 2.32.0