summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/target-helpers/drm_helper.h2
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c41
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.h1
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c16
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.h7
-rw-r--r--src/gallium/targets/pipe-loader/pipe_msm.c2
-rw-r--r--src/gallium/winsys/freedreno/drm/freedreno_drm_public.h3
-rw-r--r--src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c4
8 files changed, 66 insertions, 10 deletions
diff --git a/src/gallium/auxiliary/target-helpers/drm_helper.h b/src/gallium/auxiliary/target-helpers/drm_helper.h
index 7eefa6e42ec..bb5c5790d9d 100644
--- a/src/gallium/auxiliary/target-helpers/drm_helper.h
+++ b/src/gallium/auxiliary/target-helpers/drm_helper.h
@@ -248,7 +248,7 @@ pipe_freedreno_create_screen(int fd, const struct pipe_screen_config *config)
{
struct pipe_screen *screen;
- screen = fd_drm_screen_create(fd);
+ screen = fd_drm_screen_create(fd, NULL);
return screen ? debug_screen_wrap(screen) : NULL;
}
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index ca48fc9cee1..11319a44bb7 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -663,6 +663,9 @@ fd_resource_destroy(struct pipe_screen *pscreen,
fd_bc_invalidate_resource(rsc, true);
if (rsc->bo)
fd_bo_del(rsc->bo);
+ if (rsc->scanout)
+ renderonly_scanout_destroy(rsc->scanout, fd_screen(pscreen)->ro);
+
util_range_destroy(&rsc->valid_buffer_range);
FREE(rsc);
}
@@ -688,7 +691,7 @@ fd_resource_get_handle(struct pipe_screen *pscreen,
handle->modifier = fd_resource_modifier(rsc);
- return fd_screen_bo_get_handle(pscreen, rsc->bo,
+ return fd_screen_bo_get_handle(pscreen, rsc->bo, rsc->scanout,
rsc->slices[0].pitch * rsc->cpp, handle);
}
@@ -845,11 +848,37 @@ fd_resource_create_with_modifiers(struct pipe_screen *pscreen,
const uint64_t *modifiers, int count)
{
struct fd_screen *screen = fd_screen(pscreen);
- struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
- struct pipe_resource *prsc = &rsc->base;
+ struct fd_resource *rsc;
+ struct pipe_resource *prsc;
enum pipe_format format = tmpl->format;
uint32_t size;
+ if (screen->ro && (tmpl->bind & PIPE_BIND_SCANOUT)) {
+ struct pipe_resource scanout_templat = *tmpl;
+ struct renderonly_scanout *scanout;
+ struct winsys_handle handle;
+
+ scanout = renderonly_scanout_for_resource(&scanout_templat,
+ screen->ro, &handle);
+ if (!scanout)
+ return NULL;
+
+ renderonly_scanout_destroy(scanout, screen->ro);
+
+ assert(handle.type == WINSYS_HANDLE_TYPE_FD);
+ rsc = fd_resource(pscreen->resource_from_handle(pscreen, tmpl,
+ &handle,
+ PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE));
+ close(handle.handle);
+ if (!rsc)
+ return NULL;
+
+ return &rsc->base;
+ }
+
+ rsc = CALLOC_STRUCT(fd_resource);
+ prsc = &rsc->base;
+
DBG("%p: target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
"nr_samples=%u, usage=%u, bind=%x, flags=%x", prsc,
tmpl->target, util_format_name(format),
@@ -1050,6 +1079,12 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
assert(rsc->cpp);
+ if (screen->ro) {
+ rsc->scanout =
+ renderonly_create_gpu_import_for_resource(prsc, screen->ro, NULL);
+ /* failure is expected in some cases.. */
+ }
+
return prsc;
fail:
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 83708244857..10ab8bfa225 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -72,6 +72,7 @@ struct fd_resource {
/* buffer range that has been initialized */
struct util_range valid_buffer_range;
bool valid;
+ struct renderonly_scanout *scanout;
/* reference to the resource holding stencil data for a z32_s8 texture */
/* TODO rename to secondary or auxiliary? */
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index b372d5c5596..e596a4e8462 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -147,6 +147,9 @@ fd_screen_destroy(struct pipe_screen *pscreen)
if (screen->dev)
fd_device_del(screen->dev);
+ if (screen->ro)
+ FREE(screen->ro);
+
fd_bc_fini(&screen->batch_cache);
slab_destroy_parent(&screen->transfer_pool);
@@ -637,6 +640,7 @@ fd_get_compiler_options(struct pipe_screen *pscreen,
boolean
fd_screen_bo_get_handle(struct pipe_screen *pscreen,
struct fd_bo *bo,
+ struct renderonly_scanout *scanout,
unsigned stride,
struct winsys_handle *whandle)
{
@@ -645,6 +649,8 @@ fd_screen_bo_get_handle(struct pipe_screen *pscreen,
if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
return fd_bo_get_name(bo, &whandle->handle) == 0;
} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
+ if (renderonly_get_handle(scanout, whandle))
+ return TRUE;
whandle->handle = fd_bo_handle(bo);
return TRUE;
} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
@@ -713,7 +719,7 @@ fd_screen_bo_from_handle(struct pipe_screen *pscreen,
}
struct pipe_screen *
-fd_screen_create(struct fd_device *dev)
+fd_screen_create(struct fd_device *dev, struct renderonly *ro)
{
struct fd_screen *screen = CALLOC_STRUCT(fd_screen);
struct pipe_screen *pscreen;
@@ -734,6 +740,14 @@ fd_screen_create(struct fd_device *dev)
screen->dev = dev;
screen->refcnt = 1;
+ if (ro) {
+ screen->ro = renderonly_dup(ro);
+ if (!screen->ro) {
+ DBG("could not create renderonly object");
+ goto fail;
+ }
+ }
+
// maybe this should be in context?
screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D);
if (!screen->pipe) {
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h
index 1060f4609f6..7c457399f2a 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.h
+++ b/src/gallium/drivers/freedreno/freedreno_screen.h
@@ -34,6 +34,7 @@
#include "util/u_memory.h"
#include "util/slab.h"
#include "os/os_thread.h"
+#include "renderonly/renderonly.h"
#include "freedreno_batch_cache.h"
#include "freedreno_perfcntr.h"
@@ -101,6 +102,8 @@ struct fd_screen {
unsigned num_supported_modifiers;
const uint64_t *supported_modifiers;
+
+ struct renderonly *ro;
};
static inline struct fd_screen *
@@ -111,12 +114,14 @@ fd_screen(struct pipe_screen *pscreen)
boolean fd_screen_bo_get_handle(struct pipe_screen *pscreen,
struct fd_bo *bo,
+ struct renderonly_scanout *scanout,
unsigned stride,
struct winsys_handle *whandle);
struct fd_bo * fd_screen_bo_from_handle(struct pipe_screen *pscreen,
struct winsys_handle *whandle);
-struct pipe_screen * fd_screen_create(struct fd_device *dev);
+struct pipe_screen *
+fd_screen_create(struct fd_device *dev, struct renderonly *ro);
static inline boolean
is_a20x(struct fd_screen *screen)
diff --git a/src/gallium/targets/pipe-loader/pipe_msm.c b/src/gallium/targets/pipe-loader/pipe_msm.c
index 886fbdfc7e3..683332579fe 100644
--- a/src/gallium/targets/pipe-loader/pipe_msm.c
+++ b/src/gallium/targets/pipe-loader/pipe_msm.c
@@ -8,7 +8,7 @@ create_screen(int fd, const struct pipe_screen_config *config)
{
struct pipe_screen *screen;
- screen = fd_drm_screen_create(fd);
+ screen = fd_drm_screen_create(fd, NULL);
if (!screen)
return NULL;
diff --git a/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h b/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h
index a7ba20707d5..2f5591e867a 100644
--- a/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h
+++ b/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h
@@ -3,7 +3,8 @@
#define __FREEDRENO_DRM_PUBLIC_H__
struct pipe_screen;
+struct renderonly;
-struct pipe_screen *fd_drm_screen_create(int drmFD);
+struct pipe_screen *fd_drm_screen_create(int drmFD, struct renderonly *ro);
#endif
diff --git a/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c b/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c
index a65583f87d4..dff6209e1ef 100644
--- a/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c
+++ b/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c
@@ -85,7 +85,7 @@ static int compare_fd(void *key1, void *key2)
}
struct pipe_screen *
-fd_drm_screen_create(int fd)
+fd_drm_screen_create(int fd, struct renderonly *ro)
{
struct pipe_screen *pscreen = NULL;
@@ -104,7 +104,7 @@ fd_drm_screen_create(int fd)
if (!dev)
goto unlock;
- pscreen = fd_screen_create(dev);
+ pscreen = fd_screen_create(dev, ro);
if (pscreen) {
int fd = fd_device_fd(dev);