From fba03322a2977600ea5cd8ca0ca47aced6abf124 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Fri, 5 Apr 2019 08:13:37 +0200 Subject: [PATCH] virgl: get readback-formats from host Signed-off-by: Erik Faye-Lund Reviewed-by: Gurchetan Singh --- src/gallium/drivers/virgl/virgl_hw.h | 1 + src/gallium/drivers/virgl/virgl_screen.c | 40 ++++++++++++++++++++++++ src/gallium/drivers/virgl/virgl_screen.h | 3 ++ 3 files changed, 44 insertions(+) diff --git a/src/gallium/drivers/virgl/virgl_hw.h b/src/gallium/drivers/virgl/virgl_hw.h index 949a1f545e7..bc6803faa03 100644 --- a/src/gallium/drivers/virgl/virgl_hw.h +++ b/src/gallium/drivers/virgl/virgl_hw.h @@ -371,6 +371,7 @@ struct virgl_caps_v2 { uint32_t max_combined_atomic_counters; uint32_t max_combined_atomic_counter_buffers; uint32_t host_feature_check_version; + struct virgl_supported_format_mask supported_readback_formats; }; union virgl_caps { diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index 66fadddc262..65106dbb616 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -530,6 +530,27 @@ virgl_get_compute_param(struct pipe_screen *screen, return 0; } +static boolean +has_format_bit(struct virgl_supported_format_mask *mask, + enum virgl_formats fmt) +{ + assert(fmt < VIRGL_FORMAT_MAX); + unsigned val = (unsigned)fmt; + unsigned idx = val / 32; + unsigned bit = val % 32; + assert(idx < ARRAY_SIZE(mask->bitmask)); + return (mask->bitmask[val / 32] & (1u << bit)) != 0; +} + +boolean +virgl_has_readback_format(struct pipe_screen *screen, + enum virgl_formats fmt) +{ + struct virgl_screen *vscreen = virgl_screen(screen); + return has_format_bit(&vscreen->caps.caps.v2.supported_readback_formats, + fmt); +} + static boolean virgl_is_vertex_format_supported(struct pipe_screen *screen, enum pipe_format format) @@ -779,6 +800,24 @@ virgl_destroy_screen(struct pipe_screen *screen) FREE(vscreen); } +static void +fixup_readback_format(union virgl_caps *caps) +{ + const size_t size = ARRAY_SIZE(caps->v2.supported_readback_formats.bitmask); + for (int i = 0; i < size; ++i) { + if (caps->v2.supported_readback_formats.bitmask[i] != 0) + return; /* we got some formats, we definately have a new protocol */ + } + + /* old protocol used; fall back to considering all sampleable formats valid + * readback-formats + */ + for (int i = 0; i < size; ++i) { + caps->v2.supported_readback_formats.bitmask[i] = + caps->v1.sampler.bitmask[i]; + } +} + struct pipe_screen * virgl_create_screen(struct virgl_winsys *vws) { @@ -809,6 +848,7 @@ virgl_create_screen(struct virgl_winsys *vws) virgl_init_screen_resource_functions(&screen->base); vws->get_caps(vws, &screen->caps); + fixup_readback_format(&screen->caps.caps); screen->refcnt = 1; diff --git a/src/gallium/drivers/virgl/virgl_screen.h b/src/gallium/drivers/virgl/virgl_screen.h index 97a656fe8eb..0256d471f22 100644 --- a/src/gallium/drivers/virgl/virgl_screen.h +++ b/src/gallium/drivers/virgl/virgl_screen.h @@ -55,6 +55,9 @@ virgl_screen(struct pipe_screen *pipe) return (struct virgl_screen *)pipe; } +boolean +virgl_has_readback_format(struct pipe_screen *screen, enum virgl_formats fmt); + #define VIRGL_MAP_BUFFER_ALIGNMENT 64 #endif -- 2.30.2