broadcom/vc4: Allow importing linear BOs with arbitrary offset/stride.
authorEric Anholt <eric@anholt.net>
Tue, 6 Feb 2018 17:42:44 +0000 (17:42 +0000)
committerEric Anholt <eric@anholt.net>
Fri, 23 Feb 2018 16:42:13 +0000 (08:42 -0800)
This is part of supporting YUV textures -- MMAL will be handing us a
single GEM BO with the planes at offsets within it, and MMAL-decided
stride.

src/gallium/drivers/vc4/vc4_resource.c

index cdcbcc917e0dfbf9b4bc3b96dc6e60c092b5c9d1..202f62c8f0459dd2b42e2fb61277a8160c0a3acc 100644 (file)
@@ -708,13 +708,6 @@ vc4_resource_from_handle(struct pipe_screen *pscreen,
         if (!rsc)
                 return NULL;
 
-        if (whandle->offset != 0) {
-                fprintf(stderr,
-                        "Attempt to import unsupported winsys offset %u\n",
-                        whandle->offset);
-                return NULL;
-        }
-
         switch (whandle->type) {
         case DRM_API_HANDLE_TYPE_SHARED:
                 rsc->bo = vc4_bo_open_name(screen,
@@ -766,6 +759,28 @@ vc4_resource_from_handle(struct pipe_screen *pscreen,
         rsc->vc4_format = get_resource_texture_format(prsc);
         vc4_setup_slices(rsc, "import");
 
+        if (whandle->offset != 0) {
+                if (rsc->tiled) {
+                        fprintf(stderr,
+                                "Attempt to import unsupported "
+                                "winsys offset %u\n",
+                                whandle->offset);
+                        goto fail;
+                }
+
+                rsc->slices[0].offset += whandle->offset;
+
+                if (rsc->slices[0].offset + rsc->slices[0].size >
+                    rsc->bo->size) {
+                        fprintf(stderr, "Attempt to import "
+                                "with overflowing offset (%d + %d > %d)\n",
+                                whandle->offset,
+                                rsc->slices[0].size,
+                                rsc->bo->size);
+                        goto fail;
+                }
+        }
+
         if (screen->ro) {
                 /* Make sure that renderonly has a handle to our buffer in the
                  * display's fd, so that a later renderonly_get_handle()
@@ -779,7 +794,7 @@ vc4_resource_from_handle(struct pipe_screen *pscreen,
                         goto fail;
         }
 
-        if (whandle->stride != slice->stride) {
+        if (rsc->tiled && whandle->stride != slice->stride) {
                 static bool warned = false;
                 if (!warned) {
                         warned = true;
@@ -792,6 +807,8 @@ vc4_resource_from_handle(struct pipe_screen *pscreen,
                                 slice->stride);
                 }
                 goto fail;
+        } else if (!rsc->tiled) {
+                slice->stride = whandle->stride;
         }
 
         return prsc;