This allows creating a fd_screen with a renderonly object which will be used to allocated scanout resources. Signed-off-by: Jonathan Marek <jonathan@marek.ca> Reviewed-by: Eric Anholt <eric@anholt.net> [slight tweak to fix uninitialized 'prsc' in debug print] Signed-off-by: Rob Clark <robdclark@gmail.com>tags/19.0-branchpoint
@@ -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; | |||
} | |||
@@ -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: |
@@ -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? */ |
@@ -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) { |
@@ -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) |
@@ -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; | |||
@@ -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 |
@@ -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); | |||