diff options
Diffstat (limited to 'src/gallium/drivers/v3d')
-rw-r--r-- | src/gallium/drivers/v3d/v3d_resource.c | 57 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_resource.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_screen.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_screen.h | 4 |
4 files changed, 68 insertions, 4 deletions
diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c index 45e2edf5ab6..39529c10c4c 100644 --- a/src/gallium/drivers/v3d/v3d_resource.c +++ b/src/gallium/drivers/v3d/v3d_resource.c @@ -299,8 +299,12 @@ static void v3d_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc) { + struct v3d_screen *screen = v3d_screen(pscreen); struct v3d_resource *rsc = v3d_resource(prsc); + if (rsc->scanout) + renderonly_scanout_destroy(rsc->scanout, screen->ro); + v3d_bo_unreference(&rsc->bo); free(rsc); } @@ -312,6 +316,7 @@ v3d_resource_get_handle(struct pipe_screen *pscreen, struct winsys_handle *whandle, unsigned usage) { + struct v3d_screen *screen = v3d_screen(pscreen); struct v3d_resource *rsc = v3d_resource(prsc); struct v3d_bo *bo = rsc->bo; @@ -339,6 +344,10 @@ v3d_resource_get_handle(struct pipe_screen *pscreen, case WINSYS_HANDLE_TYPE_SHARED: return v3d_bo_flink(bo, &whandle->handle); case WINSYS_HANDLE_TYPE_KMS: + if (screen->ro) { + assert(rsc->scanout); + return renderonly_get_handle(rsc->scanout, whandle); + } whandle->handle = bo->handle; return TRUE; case WINSYS_HANDLE_TYPE_FD: @@ -633,6 +642,7 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen, const uint64_t *modifiers, int count) { + struct v3d_screen *screen = v3d_screen(pscreen); bool linear_ok = find_modifier(DRM_FORMAT_MOD_LINEAR, modifiers, count); struct v3d_resource *rsc = v3d_resource_setup(pscreen, tmpl); struct pipe_resource *prsc = &rsc->base; @@ -648,6 +658,10 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen, if (tmpl->bind & (PIPE_BIND_LINEAR | PIPE_BIND_CURSOR)) should_tile = false; + /* No tiling when we're sharing with another device (pl111). */ + if (screen->ro && (tmpl->bind & PIPE_BIND_SCANOUT)) + should_tile = false; + /* 1D and 1D_ARRAY textures are always raster-order. */ if (tmpl->target == PIPE_TEXTURE_1D || tmpl->target == PIPE_TEXTURE_1D_ARRAY) @@ -678,8 +692,32 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen, rsc->internal_format = prsc->format; v3d_setup_slices(rsc, 0); - if (!v3d_resource_bo_alloc(rsc)) - goto fail; + + /* If we're in a renderonly setup, use the other device to perform our + * (linear) allocaton 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. + * + * Note that DRI3 doesn't give us tmpl->bind flags, so we have to use + * the modifiers to see if we're allocating a scanout object. + */ + if (screen->ro && + ((tmpl->bind & PIPE_BIND_SCANOUT) || + (count == 1 && modifiers[0] == DRM_FORMAT_MOD_LINEAR))) { + struct winsys_handle handle; + rsc->scanout = + renderonly_scanout_for_resource(prsc, screen->ro, &handle); + if (!rsc->scanout) { + fprintf(stderr, "Failed to create scanout resource\n"); + goto fail; + } + assert(handle.type == WINSYS_HANDLE_TYPE_FD); + rsc->bo = v3d_bo_open_dmabuf(screen, handle.handle); + v3d_debug_resource_layout(rsc, "scanout"); + } else { + if (!v3d_resource_bo_alloc(rsc)) + goto fail; + } return prsc; fail: @@ -753,6 +791,21 @@ v3d_resource_from_handle(struct pipe_screen *pscreen, v3d_setup_slices(rsc, whandle->stride); v3d_debug_resource_layout(rsc, "import"); + 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() + * returns correct handles or GEM names. + */ + rsc->scanout = + renderonly_create_gpu_import_for_resource(prsc, + screen->ro, + NULL); + if (!rsc->scanout) { + fprintf(stderr, "Failed to create scanout resource.\n"); + goto fail; + } + } + if (whandle->stride != slice->stride) { static bool warned = false; if (!warned) { diff --git a/src/gallium/drivers/v3d/v3d_resource.h b/src/gallium/drivers/v3d/v3d_resource.h index 95ee0eb7d9c..80b1d6eb9ad 100644 --- a/src/gallium/drivers/v3d/v3d_resource.h +++ b/src/gallium/drivers/v3d/v3d_resource.h @@ -122,6 +122,7 @@ struct v3d_surface { struct v3d_resource { struct pipe_resource base; struct v3d_bo *bo; + struct renderonly_scanout *scanout; struct v3d_resource_slice slices[VC5_MAX_MIP_LEVELS]; uint32_t cube_map_stride; uint32_t size; diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index 1d59dbfc12a..4ed40ff855d 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -465,7 +465,7 @@ v3d_screen_get_compiler_options(struct pipe_screen *pscreen, } struct pipe_screen * -v3d_screen_create(int fd) +v3d_screen_create(int fd, struct renderonly *ro) { struct v3d_screen *screen = rzalloc(NULL, struct v3d_screen); struct pipe_screen *pscreen; @@ -480,6 +480,14 @@ v3d_screen_create(int fd) pscreen->is_format_supported = v3d_screen_is_format_supported; screen->fd = fd; + if (ro) { + screen->ro = renderonly_dup(ro); + if (!screen->ro) { + fprintf(stderr, "Failed to dup renderonly object\n"); + ralloc_free(screen); + return NULL; + } + } list_inithead(&screen->bo_cache.time_list); (void)mtx_init(&screen->bo_handles_mutex, mtx_plain); screen->bo_handles = util_hash_table_create(handle_hash, handle_compare); diff --git a/src/gallium/drivers/v3d/v3d_screen.h b/src/gallium/drivers/v3d/v3d_screen.h index 4d30ef30bce..6cb33429067 100644 --- a/src/gallium/drivers/v3d/v3d_screen.h +++ b/src/gallium/drivers/v3d/v3d_screen.h @@ -25,6 +25,7 @@ #define VC5_SCREEN_H #include "pipe/p_screen.h" +#include "renderonly/renderonly.h" #include "os/os_thread.h" #include "state_tracker/drm_driver.h" #include "util/list.h" @@ -55,6 +56,7 @@ struct v3d_simulator_file; struct v3d_screen { struct pipe_screen base; + struct renderonly *ro; int fd; struct v3d_device_info devinfo; @@ -90,7 +92,7 @@ v3d_screen(struct pipe_screen *screen) return (struct v3d_screen *)screen; } -struct pipe_screen *v3d_screen_create(int fd); +struct pipe_screen *v3d_screen_create(int fd, struct renderonly *ro); void v3d_fence_init(struct v3d_screen *screen); |