diff --git a/src/virgl_gbm.c b/src/virgl_gbm.c index f75ac5d..4a5879a 100644 --- a/src/virgl_gbm.c +++ b/src/virgl_gbm.c @@ -38,6 +38,48 @@ #include "virgl_hw.h" #include "vrend_debug.h" +struct planar_layout { + size_t num_planes; + int horizontal_subsampling[4]; + int vertical_subsampling[4]; + int bytes_per_pixel[4]; +}; + +static const struct planar_layout packed_1bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 1 } +}; + +static const struct planar_layout packed_2bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 2 } +}; + +static const struct planar_layout packed_4bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 4 } +}; + +static const struct planar_layout biplanar_yuv_420_layout = { + .num_planes = 2, + .horizontal_subsampling = { 1, 2 }, + .vertical_subsampling = { 1, 2 }, + .bytes_per_pixel = { 1, 2 } +}; + +static const struct planar_layout triplanar_yuv_420_layout = { + .num_planes = 3, + .horizontal_subsampling = { 1, 2, 2 }, + .vertical_subsampling = { 1, 2, 2 }, + .bytes_per_pixel = { 1, 1, 1 } +}; + static int rendernode_open(void) { DIR *dir; @@ -76,6 +118,27 @@ static int rendernode_open(void) return fd; } +static const struct planar_layout *layout_from_format(uint32_t format) +{ + switch (format) { + case GBM_FORMAT_R8: + return &packed_1bpp_layout; + case GBM_FORMAT_YVU420: + return &triplanar_yuv_420_layout; + case GBM_FORMAT_NV12: + return &biplanar_yuv_420_layout; + case GBM_FORMAT_RGB565: + return &packed_2bpp_layout; + case GBM_FORMAT_ARGB8888: + case GBM_FORMAT_XRGB8888: + case GBM_FORMAT_ABGR8888: + case GBM_FORMAT_XBGR8888: + return &packed_4bpp_layout; + default: + return NULL; + } +} + struct virgl_gbm *virgl_gbm_init(int fd) { struct virgl_gbm *gbm = calloc(1, sizeof(struct virgl_gbm)); @@ -117,11 +180,23 @@ void virgl_gbm_fini(struct virgl_gbm *gbm) uint32_t virgl_gbm_convert_format(uint32_t virgl_format) { switch (virgl_format) { - case VIRGL_FORMAT_B8G8R8X8_UNORM: + 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: - vrend_printf("unsupported virgl format: %u\n", virgl_format); return 0; } } diff --git a/tests/test_virgl_init.c b/tests/test_virgl_init.c index 56da937..a6ff8fd 100644 --- a/tests/test_virgl_init.c +++ b/tests/test_virgl_init.c @@ -330,7 +330,8 @@ START_TEST(virgl_test_get_resource_info) ck_assert_int_eq(ret, 0); ck_assert(info.drm_fourcc == GBM_FORMAT_ABGR8888 || - info.drm_fourcc == GBM_FORMAT_ARGB8888); + info.drm_fourcc == GBM_FORMAT_ARGB8888 || + info.drm_fourcc == GBM_FORMAT_XRGB8888); ck_assert_int_eq(info.virgl_format, res.format); ck_assert_int_eq(res.width, info.width); ck_assert_int_eq(res.height, info.height);