summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/v3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/v3d')
-rw-r--r--src/gallium/drivers/v3d/v3d_resource.c57
-rw-r--r--src/gallium/drivers/v3d/v3d_resource.h1
-rw-r--r--src/gallium/drivers/v3d/v3d_screen.c10
-rw-r--r--src/gallium/drivers/v3d/v3d_screen.h4
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);