[Mesa-dev] [PATCH] i965: implement (un)mapImage
Chris Wilson
chris at chris-wilson.co.uk
Tue Nov 14 10:02:43 UTC 2017
Quoting Julien Isorce (2017-11-09 17:03:13)
> v2: add early return if (flag & MAP_INTERNAL_MASK)
> v3: take input rect into account and test with kmscube and piglit.
> v4: handle wraparound and bo reference.
>
> Already implemented for Gallium drivers.
>
> Useful for gbm_bo_(un)map.
>
> Tests:
> By porting wayland/weston/clients/simple-dmabuf-drm.c to GBM.
> kmscube --mode=rgba
> kmscube --mode=nv12-1img
> kmscube --mode=nv12-2img
> piglit ext_image_dma_buf_import-refcount -auto
> piglit ext_image_dma_buf_import-transcode-nv12-as-r8-gr88 -auto
> piglit ext_image_dma_buf_import-sample_rgb -fmt=AR24 -alpha-one -auto
> piglit ext_image_dma_buf_import-sample_rgb -fmt=XR24 -auto
> piglit ext_image_dma_buf_import-sample_yuv -fmt=NV12 -auto
> piglit ext_image_dma_buf_import-sample_yuv -fmt=YU12 -auto
> piglit ext_image_dma_buf_import-sample_yuv -fmt=YV12 -auto
>
> Signed-off-by: Julien Isorce <jisorce at oblong.com>
> ---
> src/mesa/drivers/dri/i965/intel_screen.c | 75 +++++++++++++++++++++++++++++++-
> 1 file changed, 73 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
> index cdc36ad..6074ee8 100644
> --- a/src/mesa/drivers/dri/i965/intel_screen.c
> +++ b/src/mesa/drivers/dri/i965/intel_screen.c
> @@ -755,6 +755,77 @@ intel_create_image(__DRIscreen *dri_screen,
> loaderPrivate);
> }
>
> +static void *
> +intel_map_image(__DRIcontext *context, __DRIimage *image,
> + int x0, int y0, int width, int height,
> + unsigned int flags, int *stride, void **map_info)
> +{
> + struct brw_context *brw = NULL;
> + struct brw_bo *bo = NULL;
> + void *raw_data = NULL;
> +
> + if (!context || !image || !stride || !map_info || *map_info)
> + return NULL;
> +
> + if (x0 < 0 || x0 > image->width || width > image->width - x0)
> + return NULL;
Second careful thought here is that you want x0 >= image->width so that
we correctly exclude a 0 width request on the boundary. Or reject 0
width/height.
> +
> + if (y0 < 0 || y0 > image->height || height > image->height - y0)
> + return NULL;
> +
> + if (flags & MAP_INTERNAL_MASK)
> + return NULL;
> +
> + brw = context->driverPrivate;
> + bo = image->bo;
> +
> + assert(brw);
> + assert(bo);
> +
> + brw_bo_reference(bo);
> +
> + /* DRI flags and GL_MAP.*_BIT flags are the same, so just pass them on. */
> + raw_data = brw_bo_map(brw, bo, flags);
> +
> + if (raw_data) {
> + GLuint pix_w = 1;
> + GLuint pix_h = 1;
> + GLint pix_bytes = 1;
> +
> + *map_info = raw_data;
> + *stride = image->pitch;
> +
> + _mesa_get_format_block_size(image->format, &pix_w, &pix_h);
> + pix_bytes = _mesa_get_format_bytes(image->format);
> +
> + assert(pix_w);
> + assert(pix_h);
> + assert(pix_bytes > 0);
> +
> + raw_data += ((x0 / pix_w) * pix_bytes) + (y0 / pix_h) * image->pitch;
Ok, this matches up with similar code for intel_miptree_map_gtt().
> + } else {
> + brw_bo_unreference(bo);
> + }
Going back to Ben's patch, the rationale for ref/unref was that we could
map the bo independently of the image; i.e. later on image->bo may be
pointing to something else.
So *map_info = brw_bo_reference(bo); in intel_map_image() and
brw_bo_unreference(map_info) here.
Taking the suggestions from elsewhere;
raw_data = brw_bo_map(brw, image->bo, flags);
if (!raw_data)
return NULL;
...
_mesa_get_format_block_size();
_mesa_get_format_bytes;
raw_data += x0 / pix_w * pix_bytes + y0 / pix_h * image->pitch;
*stride = image->pitch;
*map_info = brw_bo_reference(image->bo);
return raw_data;
-Chris
More information about the mesa-dev
mailing list