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: