i965: implement (un)mapImage
authorJulien Isorce <jisorce@oblong.com>
Mon, 6 Nov 2017 10:08:25 +0000 (10:08 +0000)
committerJulien Isorce <jisorce@oblong.com>
Tue, 14 Nov 2017 14:23:13 +0000 (14:23 +0000)
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=XR24 -alpha-one -auto
  piglit ext_image_dma_buf_import-sample_rgb -fmt=AR24 -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

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.
v5: indent, exclude 0 width and height on the boundary, map bo
    independently of the image.

Signed-off-by: Julien Isorce <jisorce@oblong.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
src/mesa/drivers/dri/i965/intel_screen.c

index 3d238769ad073764ccbcb8344dc7e0399fc6244c..4e48a856050340af1c4ba6befd7a8cf27079de99 100644 (file)
@@ -755,6 +755,67 @@ 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;
+   GLuint pix_w = 1;
+   GLuint pix_h = 1;
+   GLint pix_bytes = 1;
+
+   if (!context || !image || !stride || !map_info || *map_info)
+      return NULL;
+
+   if (x0 < 0 || x0 >= image->width || width > image->width - x0)
+      return NULL;
+
+   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);
+
+   /* 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)
+      return NULL;
+
+   _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;
+
+   brw_bo_reference(bo);
+
+   *stride = image->pitch;
+   *map_info = bo;
+
+   return raw_data;
+}
+
+static void
+intel_unmap_image(__DRIcontext *context, __DRIimage *image, void *map_info)
+{
+   struct brw_bo *bo = map_info;
+
+   brw_bo_unmap(bo);
+   brw_bo_unreference(bo);
+}
+
 static __DRIimage *
 intel_create_image_with_modifiers(__DRIscreen *dri_screen,
                                   int width, int height, int format,
@@ -1305,8 +1366,8 @@ static const __DRIimageExtension intelImageExtension = {
     .createImageFromDmaBufs             = intel_create_image_from_dma_bufs,
     .blitImage                          = NULL,
     .getCapabilities                    = NULL,
-    .mapImage                           = NULL,
-    .unmapImage                         = NULL,
+    .mapImage                           = intel_map_image,
+    .unmapImage                         = intel_unmap_image,
     .createImageWithModifiers           = intel_create_image_with_modifiers,
     .createImageFromDmaBufs2            = intel_create_image_from_dma_bufs2,
     .queryDmaBufFormats                 = intel_query_dma_buf_formats,