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).
This commit is contained in:
Eric Anholt 2019-03-18 14:19:36 -07:00
parent eb5903a908
commit bf6973199d

View file

@ -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: