summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/v3d
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2019-03-18 14:19:36 -0700
committerEric Anholt <[email protected]>2019-03-19 08:54:46 -0700
commitbf6973199d186c93da35becc695db58fd3d1b4e5 (patch)
tree1eced23ba28707140c1d9617531b5e6f9ea7dd97 /src/gallium/drivers/v3d
parenteb5903a90857e767233fc818c2c07abd92d79521 (diff)
v3d: Allow the UIF modifier with renderonly.
We ask the other side to make a buffer with the right number of pages, and then just store the UIF in it. This avoids an extra silent copy of the buffer from linear to UIF if it gets used for texturing (X11 copy-based swapbuffers, GL compositors).
Diffstat (limited to 'src/gallium/drivers/v3d')
-rw-r--r--src/gallium/drivers/v3d/v3d_resource.c90
1 files changed, 52 insertions, 38 deletions
diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c
index 61432a09d2f..10abee4e8f6 100644
--- a/src/gallium/drivers/v3d/v3d_resource.c
+++ b/src/gallium/drivers/v3d/v3d_resource.c
@@ -403,7 +403,9 @@ v3d_resource_get_handle(struct pipe_screen *pscreen,
case WINSYS_HANDLE_TYPE_KMS:
if (screen->ro) {
assert(rsc->scanout);
- return renderonly_get_handle(rsc->scanout, whandle);
+ bool ok = renderonly_get_handle(rsc->scanout, whandle);
+ whandle->stride = rsc->slices[0].stride;
+ return ok;
}
whandle->handle = bo->handle;
return TRUE;
@@ -696,41 +698,6 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen,
{
struct v3d_screen *screen = v3d_screen(pscreen);
- /* If we're in a renderonly setup, use the other device to perform our
- * (linear) allocation and just import it to v3d. The other device
- * may be using CMA, and V3D can import from CMA but doesn't do CMA
- * allocations on its own.
- *
- * We always allocate this way for SHARED, because get_handle will
- * need a resource on the display fd.
- */
- if (screen->ro && (tmpl->bind & (PIPE_BIND_SCANOUT |
- PIPE_BIND_SHARED))) {
- struct winsys_handle handle;
- struct pipe_resource scanout_tmpl = *tmpl;
- struct renderonly_scanout *scanout =
- renderonly_scanout_for_resource(&scanout_tmpl,
- screen->ro,
- &handle);
- if (!scanout) {
- fprintf(stderr, "Failed to create scanout resource\n");
- return NULL;
- }
- assert(handle.type == WINSYS_HANDLE_TYPE_FD);
- /* The fd is all we need. Destroy the old scanout (and its
- * GEM handle on kms_fd) before resource_from_handle()'s
- * renderonly_create_gpu_import_for_resource() call which will
- * also get a kms_fd GEM handle for the fd.
- */
- renderonly_scanout_destroy(scanout, screen->ro);
- struct pipe_resource *prsc =
- pscreen->resource_from_handle(pscreen, tmpl,
- &handle,
- PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
- close(handle.handle);
- return prsc;
- }
-
bool linear_ok = drm_find_modifier(DRM_FORMAT_MOD_LINEAR, modifiers, count);
struct v3d_resource *rsc = v3d_resource_setup(pscreen, tmpl);
struct pipe_resource *prsc = &rsc->base;
@@ -758,6 +725,12 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen,
tmpl->bind & (PIPE_BIND_SHARED | PIPE_BIND_SCANOUT))
should_tile = false;
+ /* If using the old-school SCANOUT flag, we don't know what the screen
+ * might support other than linear. Just force linear.
+ */
+ if (tmpl->bind & PIPE_BIND_SCANOUT)
+ should_tile = false;
+
/* No user-specified modifier; determine our own. */
if (count == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID) {
linear_ok = true;
@@ -777,8 +750,49 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen,
v3d_setup_slices(rsc, 0, tmpl->bind & PIPE_BIND_SHARED);
- if (!v3d_resource_bo_alloc(rsc))
- goto fail;
+ /* If we're in a renderonly setup, use the other device to perform our
+ * allocation and just import it to v3d. The other device may be
+ * using CMA, and V3D can import from CMA but doesn't do CMA
+ * allocations on its own.
+ *
+ * We always allocate this way for SHARED, because get_handle will
+ * need a resource on the display fd.
+ */
+ if (screen->ro && (tmpl->bind & (PIPE_BIND_SCANOUT |
+ PIPE_BIND_SHARED))) {
+ struct winsys_handle handle;
+ struct pipe_resource scanout_tmpl = {
+ .target = prsc->target,
+ .format = PIPE_FORMAT_RGBA8888_UNORM,
+ .width0 = 1024, /* one page */
+ .height0 = align(rsc->size, 4096) / 4096,
+ .depth0 = 1,
+ .array_size = 1,
+ };
+
+ rsc->scanout =
+ renderonly_scanout_for_resource(&scanout_tmpl,
+ screen->ro,
+ &handle);
+
+ if (!rsc->scanout) {
+ fprintf(stderr, "Failed to create scanout resource\n");
+ return NULL;
+ }
+ assert(handle.type == WINSYS_HANDLE_TYPE_FD);
+ rsc->bo = v3d_bo_open_dmabuf(screen, handle.handle);
+ close(handle.handle);
+
+ if (!rsc->bo)
+ goto fail;
+
+ v3d_debug_resource_layout(rsc, "renderonly");
+
+ return prsc;
+ } else {
+ if (!v3d_resource_bo_alloc(rsc))
+ goto fail;
+ }
return prsc;
fail: