summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Faye-Lund <erik.faye-lund@collabora.com>2019-04-05 08:13:37 +0200
committerErik Faye-Lund <erik.faye-lund@collabora.com>2019-04-17 07:27:08 +0000
commitfba03322a2977600ea5cd8ca0ca47aced6abf124 (patch)
treebbb9d3ed4c829c7d12e1d6cdba97496f11b841ac
parent749bbd39c719a600cd2555932bb47aa73ca42336 (diff)
virgl: get readback-formats from host
Signed-off-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
-rw-r--r--src/gallium/drivers/virgl/virgl_hw.h1
-rw-r--r--src/gallium/drivers/virgl/virgl_screen.c40
-rw-r--r--src/gallium/drivers/virgl/virgl_screen.h3
3 files changed, 44 insertions, 0 deletions
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
@@ -531,6 +531,27 @@ virgl_get_compute_param(struct pipe_screen *screen,
}
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