diff --git a/src/virgl_egl_context.c b/src/virgl_egl_context.c index d70ca3b..a25bd1c 100644 --- a/src/virgl_egl_context.c +++ b/src/virgl_egl_context.c @@ -276,6 +276,7 @@ virgl_renderer_gl_context virgl_egl_get_current_context(UNUSED struct virgl_egl int virgl_egl_get_fourcc_for_texture(struct virgl_egl *egl, uint32_t tex_id, uint32_t format, int *fourcc) { int ret = EINVAL; + uint32_t gbm_format = 0; EGLImageKHR image; EGLBoolean success; @@ -300,7 +301,8 @@ int virgl_egl_get_fourcc_for_texture(struct virgl_egl *egl, uint32_t tex_id, uin return ret; fallback: - *fourcc = virgl_gbm_convert_format(format); + ret = virgl_gbm_convert_format(&format, &gbm_format); + *fourcc = (int)gbm_format; return ret; } diff --git a/src/virgl_gbm.c b/src/virgl_gbm.c index 68d1c01..765df27 100644 --- a/src/virgl_gbm.c +++ b/src/virgl_gbm.c @@ -49,6 +49,11 @@ struct planar_layout { int bytes_per_pixel[4]; }; +struct format_conversion { + uint32_t gbm_format; + uint32_t virgl_format; +}; + static const struct planar_layout packed_1bpp_layout = { .num_planes = 1, .horizontal_subsampling = { 1 }, @@ -84,6 +89,17 @@ static const struct planar_layout triplanar_yuv_420_layout = { .bytes_per_pixel = { 1, 1, 1 } }; +static const struct format_conversion conversions[] = { + { GBM_FORMAT_RGB565, VIRGL_FORMAT_B5G6R5_UNORM }, + { GBM_FORMAT_ARGB8888, VIRGL_FORMAT_B8G8R8A8_UNORM }, + { GBM_FORMAT_XRGB8888, VIRGL_FORMAT_B8G8R8X8_UNORM }, + { GBM_FORMAT_NV12, VIRGL_FORMAT_NV12 }, + { GBM_FORMAT_ABGR8888, VIRGL_FORMAT_R8G8B8A8_UNORM}, + { GBM_FORMAT_XBGR8888, VIRGL_FORMAT_R8G8B8X8_UNORM}, + { GBM_FORMAT_R8, VIRGL_FORMAT_R8_UNORM}, + { GBM_FORMAT_YVU420, VIRGL_FORMAT_YV12} +}; + static int rendernode_open(void) { DIR *dir; @@ -267,28 +283,25 @@ void virgl_gbm_fini(struct virgl_gbm *gbm) free(gbm); } -uint32_t virgl_gbm_convert_format(uint32_t virgl_format) +int virgl_gbm_convert_format(uint32_t *virgl_format, uint32_t *gbm_format) { - switch (virgl_format) { - case VIRGL_FORMAT_B5G6R5_UNORM: - return GBM_FORMAT_RGB565; - case VIRGL_FORMAT_B8G8R8A8_UNORM: - return GBM_FORMAT_ARGB8888; - case VIRGL_FORMAT_B8G8R8X8_UNORM: - return GBM_FORMAT_XRGB8888; - case VIRGL_FORMAT_NV12: - return GBM_FORMAT_NV12; - case VIRGL_FORMAT_R8G8B8A8_UNORM: - return GBM_FORMAT_ABGR8888; - case VIRGL_FORMAT_R8G8B8X8_UNORM: - return GBM_FORMAT_XBGR8888; - case VIRGL_FORMAT_R8_UNORM: - return GBM_FORMAT_R8; - case VIRGL_FORMAT_YV12: - return GBM_FORMAT_YVU420; - default: - return 0; - } + + if (!virgl_format || !gbm_format) + return -1; + + if (*virgl_format != 0 && *gbm_format != 0) + return -1; + + for (uint32_t i = 0; i < ARRAY_SIZE(conversions); i++) { + if (conversions[i].gbm_format == *gbm_format || + conversions[i].virgl_format == *virgl_format) { + *gbm_format = conversions[i].gbm_format; + *virgl_format = conversions[i].virgl_format; + return 0; + } + } + + return -1; } int virgl_gbm_transfer(struct gbm_bo *bo, uint32_t direction, struct iovec *iovecs, diff --git a/src/virgl_gbm.h b/src/virgl_gbm.h index a852718..f2cc90f 100644 --- a/src/virgl_gbm.h +++ b/src/virgl_gbm.h @@ -43,7 +43,7 @@ struct virgl_gbm *virgl_gbm_init(int fd); void virgl_gbm_fini(struct virgl_gbm *gbm); -uint32_t virgl_gbm_convert_format(uint32_t virgl_format); +int virgl_gbm_convert_format(uint32_t *virgl_format, uint32_t *gbm_format); int virgl_gbm_transfer(struct gbm_bo *bo, uint32_t direction, struct iovec *iovecs, uint32_t num_iovecs, const struct vrend_transfer_info *info); diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index e42a3ed..e95f07e 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -691,7 +691,10 @@ static inline bool vrend_format_is_ds(enum virgl_formats format) static inline bool vrend_format_can_scanout(enum virgl_formats format) { #ifdef ENABLE_GBM_ALLOCATION - uint32_t gbm_format = virgl_gbm_convert_format(format); + uint32_t gbm_format = 0; + if (virgl_gbm_convert_format(&format, &gbm_format)) + return false; + if (!gbm || !gbm->device || !gbm_format) return false; @@ -6155,7 +6158,10 @@ static void *vrend_allocate_using_gbm(struct vrend_resource *gr) { #ifdef ENABLE_GBM_ALLOCATION uint32_t gbm_flags = virgl_gbm_convert_flags(gr->base.bind); - uint32_t gbm_format = virgl_gbm_convert_format(gr->base.format); + uint32_t gbm_format = 0; + if (virgl_gbm_convert_format(&gr->base.format, &gbm_format)) + return false; + if (gr->base.depth0 != 1 || gr->base.last_level != 0 || gr->base.nr_samples != 0) return NULL;